Updates for Django 1.10 and 1.11 (#73)

This commit is contained in:
Alexey Kotlyarov 2017-04-20 21:33:28 +10:00 committed by Cédric Carrard
parent 59283a1af4
commit a98318f5bf
9 changed files with 171 additions and 50 deletions

View file

@ -3,14 +3,30 @@ language: python
python:
- "2.7"
- "3.4"
- "3.6"
cache: pip
env:
- DJANGO_VERSION=1.5.2
- DJANGO_VERSION=1.6.5
- DJANGO_VERSION=1.7.0
- DJANGO_VERSION=1.8.0
- DJANGO_VERSION=1.8.6
- DJANGO_VERSION=1.9.4
- DJANGO_VERSION=1.5.*
- DJANGO_VERSION=1.6.*
- DJANGO_VERSION=1.7.*
- DJANGO_VERSION=1.8.*
- DJANGO_VERSION=1.9.*
- DJANGO_VERSION=1.10.*
- DJANGO_VERSION=1.11.*
matrix:
exclude:
- python: '3.6'
env: DJANGO_VERSION=1.5.*
- python: '3.6'
env: DJANGO_VERSION=1.6.*
- python: '3.6'
env: DJANGO_VERSION=1.7.*
- python: '3.6'
env: DJANGO_VERSION=1.8.*
- python: '3.6'
env: DJANGO_VERSION=1.9.*
- python: '3.6'
env: DJANGO_VERSION=1.10.*
install:
- pip install -q Django==$DJANGO_VERSION
- pip install coveralls

View file

@ -37,14 +37,22 @@ Quick start
#. Add ``embed_video`` to ``INSTALLED_APPS`` in your Django settings.
#. If you want to detect HTTP/S in template tags, you have to set ``request``
context processor in ``settings.TEMPLATE_CONTEXT_PROCESSORS``:
context processor in ``settings.TEMPLATES``:
::
TEMPLATE_CONTEXT_PROCESSORS = (
...
'django.core.context_processors.request',
)
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# ...
'OPTIONS': {
'context_processors': [
# ...
'django.template.context_processors.request',
],
},
},
]
#. Usage of template tags:

View file

@ -1,13 +1,29 @@
import os
from django.conf.global_settings import *
DEBUG = True
SECRET_KEY = 'testing_key123'
STATIC_ROOT = MEDIA_ROOT = os.path.join(os.path.dirname(__file__), 'static')
STATIC_URL = MEDIA_URL = '/static/'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
],
},
},
]
INSTALLED_APPS = (
'django.contrib.contenttypes',
'django.contrib.auth',

View file

@ -1,9 +1,15 @@
from unittest import TestCase, skip
from mock import Mock, patch
import sys
import re
if sys.version_info.major == 3:
import urllib.parse as urlparse
else:
import urlparse
from django.template import TemplateSyntaxError
from django.http import HttpRequest
from django.http import HttpRequest, QueryDict
from django.template.base import Template
from django.template.context import RequestContext
from django.test.client import RequestFactory
@ -15,10 +21,38 @@ URL_PATTERN = re.compile(r'src="?\'?([^"\'>]*)"')
class EmbedTestCase(TestCase):
def assertRenderedTemplate(self, template_string, output, context=None):
def render_template(self, template_string, context=None):
response = RequestContext(HttpRequest(), context)
rendered_output = Template(template_string).render(response)
self.assertEqual(rendered_output.strip(), output.strip())
return Template(template_string).render(response).strip()
def assertRenderedTemplate(self, template_string, output, context=None):
rendered_output = self.render_template(template_string, context=context)
self.assertEqual(rendered_output, output.strip())
def url_dict(self, url):
"""
Parse the URL into a format suitable for comparison, ignoring the query
parameter order.
"""
parsed = urlparse.urlparse(url)
query = urlparse.parse_qs(parsed.query)
return {
'scheme': parsed.scheme,
'netloc': parsed.netloc,
'path': parsed.path,
'params': parsed.params,
'query': query,
'fragment': parsed.fragment,
}
def assertUrlEqual(self, actual, expected, msg=None):
"""Assert two URLs are equal, ignoring the query parameter order."""
actual_dict = self.url_dict(actual)
expected_dict = self.url_dict(expected)
self.assertEqual(actual_dict, expected_dict, msg=msg)
def test_embed(self):
template = """
@ -195,9 +229,11 @@ class EmbedTestCase(TestCase):
{{ ytb.url }}
{% endvideo %}
"""
self.assertRenderedTemplate(
template,
'http://www.youtube.com/embed/jsrRJyHBvzw?wmode=transparent&rel=1'
output = self.render_template(template)
self.assertUrlEqual(
output,
'http://www.youtube.com/embed/jsrRJyHBvzw?rel=1&wmode=transparent'
)
def test_direct_embed_with_query(self):
@ -206,10 +242,25 @@ class EmbedTestCase(TestCase):
{% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' query="rel=1&wmode=transparent" %}
"""
self.assertRenderedTemplate(
template,
output = self.render_template(template)
# The order of query parameters in the URL might change between Python
# versions. Compare the URL and the outer part separately.
url_pattern = re.compile(r'http[^"]+')
url = url_pattern.search(output).group(0)
self.assertUrlEqual(
url,
'http://www.youtube.com/embed/jsrRJyHBvzw?rel=1&wmode=transparent'
)
output_without_url = url_pattern.sub('URL', output)
self.assertEqual(
output_without_url,
'<iframe width="480" height="360" '
'src="http://www.youtube.com/embed/jsrRJyHBvzw?wmode=transparent&rel=1" '
'src="URL" '
'frameborder="0" allowfullscreen></iframe>'
)

View file

@ -1,11 +1,13 @@
from unittest import TestCase
from django.test import SimpleTestCase
from embed_video.admin import AdminVideoWidget, AdminVideoMixin
from embed_video.backends import VimeoBackend
from embed_video.fields import EmbedVideoField, EmbedVideoFormField
class AdminVideoWidgetTestCase(TestCase):
class AdminVideoWidgetTestCase(SimpleTestCase):
def test_size(self):
widget = AdminVideoWidget()
self.assertTrue('size' in widget.attrs)
@ -21,15 +23,15 @@ class AdminVideoWidgetTestCase(TestCase):
def test_render_empty_value(self):
widget = AdminVideoWidget(attrs={'size': '0'})
self.assertEqual(widget.render('foo'),
'<input name="foo" size="0" type="text" />')
self.assertHTMLEqual(widget.render('foo'),
'<input name="foo" size="0" type="text" />')
def test_render(self):
backend = VimeoBackend('https://vimeo.com/1')
widget = AdminVideoWidget(attrs={'size': '0'})
widget.output_format = '{video}{input}'
self.assertEqual(
self.assertHTMLEqual(
widget.render('foo', backend.url, size=(100, 100)),
backend.get_embed_code(100, 100)
+ '<input name="foo" size="0" type="text" value="%s" />'
@ -38,14 +40,14 @@ class AdminVideoWidgetTestCase(TestCase):
def test_render_unknown_backend(self):
widget = AdminVideoWidget()
self.assertEqual(
self.assertHTMLEqual(
widget.render('foo', 'abcd'),
'<input name="foo" size="40" type="text" value="abcd" />'
)
def test_render_video_doesnt_exist(self):
widget = AdminVideoWidget()
self.assertEqual(
self.assertHTMLEqual(
widget.render('foo', 'https://soundcloud.com/xyz/foo'),
'<input name="foo" size="40" type="text" value="https://soundcloud.com/xyz/foo" />'
)

View file

@ -7,6 +7,10 @@ Running example project
#. Create database::
python manage.py migrate --run-syncdb --noinput
Or, for older versions of Django::
python manage.py syncdb --noinput
#. Run testing server::

View file

@ -1,7 +1,7 @@
# Django settings for example_project project.
import django
DEBUG = True
TEMPLATE_DEBUG = DEBUG
DATABASES = {
'default': {
@ -14,21 +14,45 @@ SITE_ID = 1
SECRET_KEY = 'u%38dln@$1!7w#cxi4np504^sa3_skv5aekad)jy_u0v2mc+nr'
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.core.context_processors.tz',
'django.contrib.messages.context_processors.messages',
'django.core.context_processors.request',
)
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
if django.VERSION >= (1, 10):
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
else:
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
APPEND_SLASH = True

View file

@ -1,11 +1,11 @@
from django.conf.urls import patterns, include, url
from django.conf.urls import include, url
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.contrib import admin
admin.autodiscover()
urlpatterns = staticfiles_urlpatterns() \
+ patterns('',
+ [
url(r'^admin/', include(admin.site.urls)),
url(r'^', include('posts.urls', namespace='posts')),
)
]

View file

@ -1,8 +1,8 @@
from django.conf.urls import patterns, url
from django.conf.urls import url
from .views import PostListView, PostDetailView
urlpatterns = patterns('',
urlpatterns = [
url(r'(?P<pk>\d+)/$', PostDetailView.as_view(), name='detail'),
url(r'$', PostListView.as_view(), name='list'),
)
]