From 6cbbb6bd1f76fa71cf0c1fbfe846ee8b22637474 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=89lie=20Bouttier?=
Date: Sun, 10 Dec 2017 13:32:19 +0100
Subject: [PATCH] django 2.0
---
accounts/models.py | 4 +-
accounts/urls.py | 13 +--
cfp/converters.py | 8 ++
cfp/decorators.py | 6 +-
cfp/models.py | 18 +--
cfp/planning.py | 6 +-
cfp/signals.py | 2 +-
cfp/templates/cfp/schedule.html | 2 +-
cfp/templates/cfp/staff/schedule.html | 2 +-
cfp/templates/cfp/staff/talk_details.html | 10 +-
cfp/tests.py | 97 ++++++++--------
cfp/urls.py | 133 +++++++++++-----------
cfp/views.py | 19 ++--
mailing/models.py | 6 +-
mailing/tests.py | 2 +-
ponyconf/settings.py | 1 -
ponyconf/urls.py | 27 +----
requirements.in | 4 +-
requirements.txt | 10 +-
19 files changed, 181 insertions(+), 189 deletions(-)
create mode 100644 cfp/converters.py
diff --git a/accounts/models.py b/accounts/models.py
index 146f0fe..072ebe2 100644
--- a/accounts/models.py
+++ b/accounts/models.py
@@ -1,12 +1,12 @@
from django.contrib.auth.models import User
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django.db import models
from django.utils.translation import ugettext_lazy as _
class Profile(models.Model):
- user = models.OneToOneField(User)
+ user = models.OneToOneField(User, on_delete=models.CASCADE)
phone_number = models.CharField(max_length=16, blank=True, default='', verbose_name=_('Phone number'))
sms_prefered = models.BooleanField(default=False, verbose_name=_('SMS prefered'))
biography = models.TextField(blank=True, verbose_name=_('Biography'))
diff --git a/accounts/urls.py b/accounts/urls.py
index fe35a6d..750b1dc 100644
--- a/accounts/urls.py
+++ b/accounts/urls.py
@@ -1,15 +1,12 @@
from django.conf import settings
-from django.conf.urls import include, url
+from django.urls import include, path
from django.contrib.auth import views as auth_views
from . import views
urlpatterns = [
- url(r'^profile/$', views.profile, name='profile'),
- url(r'accounts/login/', views.EmailLoginView.as_view(), {'extra_context': {'buttons': [views.RESET_PASSWORD_BUTTON]}}, name='login'),
- #url(r'^login/$', auth_views.login, {'extra_context': {'buttons': [views.RESET_PASSWORD_BUTTON]}}, name='login'),
- url(r'^logout/$', auth_views.logout, {'next_page': settings.LOGOUT_REDIRECT_URL}, name='logout'),
- #url(r'^avatar/', include('avatar.urls')),
- url(r'', include('django.contrib.auth.urls')),
- #url(r'', include('registration.backends.default.urls')),
+ path('profile/', views.profile, name='profile'),
+ path('accounts/login/', views.EmailLoginView.as_view(), {'extra_context': {'buttons': [views.RESET_PASSWORD_BUTTON]}}, name='login'),
+ path('logout/', auth_views.logout, {'next_page': settings.LOGOUT_REDIRECT_URL}, name='logout'),
+ path('', include('django.contrib.auth.urls')),
]
diff --git a/cfp/converters.py b/cfp/converters.py
new file mode 100644
index 0000000..e42ef99
--- /dev/null
+++ b/cfp/converters.py
@@ -0,0 +1,8 @@
+class SignedIntConverter:
+ regex = '[+-]?[0-9]+'
+
+ def to_python(self, value):
+ return int(value)
+
+ def to_url(self, value):
+ return '%+d' % value
diff --git a/cfp/decorators.py b/cfp/decorators.py
index 5caaf20..312814f 100644
--- a/cfp/decorators.py
+++ b/cfp/decorators.py
@@ -19,7 +19,7 @@ def speaker_required(view_func):
except ValueError:
raise Http404
speaker = get_object_or_404(Participant, site=request.conference.site, token=speaker_token)
- elif request.user.is_authenticated():
+ elif request.user.is_authenticated:
speaker = get_object_or_404(Participant, site=request.conference.site, email=request.user.email)
else:
raise PermissionDenied
@@ -37,7 +37,7 @@ def volunteer_required(view_func):
except ValueError:
raise Http404
volunteer = get_object_or_404(Volunteer, site=request.conference.site, token=volunteer_token)
- elif request.user.is_authenticated():
+ elif request.user.is_authenticated:
volunteer = get_object_or_404(Volunteer, site=request.conference.site, email=request.user.email)
else:
raise PermissionDenied
@@ -48,7 +48,7 @@ def volunteer_required(view_func):
def staff_required(view_func):
def _is_staff(request, *args, **kwargs):
- if not request.user.is_authenticated():
+ if not request.user.is_authenticated:
return login_required(view_func)(request, *args, **kwargs)
elif is_staff(request, request.user):
return view_func(request, *args, **kwargs)
diff --git a/cfp/models.py b/cfp/models.py
index e1a95d0..ff9d025 100644
--- a/cfp/models.py
+++ b/cfp/models.py
@@ -1,6 +1,6 @@
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django.core.validators import MaxValueValidator, MinValueValidator
from django.core.exceptions import ValidationError
from django.db import models
@@ -117,7 +117,7 @@ class Participant(PonyConfModel):
notes = models.TextField(default='', blank=True, verbose_name=_("Notes"),
help_text=_('This field is only visible by organizers.'))
vip = models.BooleanField(default=False, verbose_name=_('Invited speaker'))
- conversation = models.OneToOneField(MessageThread)
+ conversation = models.OneToOneField(MessageThread, on_delete=models.PROTECT)
objects = ParticipantManager()
@@ -332,14 +332,14 @@ class Talk(PonyConfModel):
slug = AutoSlugField(populate_from='title', unique=True)
description = models.TextField(verbose_name=_('Description of your talk'),
help_text=_('This description will be visible on the program.'))
- track = models.ForeignKey(Track, blank=True, null=True, verbose_name=_('Track'))
+ track = models.ForeignKey(Track, blank=True, null=True, verbose_name=_('Track'), on_delete=models.SET_NULL)
tags = models.ManyToManyField(Tag, blank=True)
notes = models.TextField(blank=True, verbose_name=_('Message to organizers'),
help_text=_('If you have any constraint or if you have anything that may '
'help you to select your talk, like a video or slides of your'
' talk, please write it down here. This field will only be '
'visible by organizers.'))
- category = models.ForeignKey(TalkCategory, verbose_name=_('Talk Category'))
+ category = models.ForeignKey(TalkCategory, verbose_name=_('Talk Category'), on_delete=models.PROTECT)
videotaped = models.BooleanField(_("I'm ok to be recorded on video"), default=True)
video_licence = models.CharField(choices=LICENCES, default='CC-BY-SA',
max_length=10, verbose_name=_("Video licence"))
@@ -348,13 +348,13 @@ class Talk(PonyConfModel):
confirmed = models.NullBooleanField(default=None)
start_date = models.DateTimeField(null=True, blank=True, default=None, verbose_name=_('Beginning date and time'))
duration = models.PositiveIntegerField(default=0, verbose_name=_('Duration (min)'))
- room = models.ForeignKey(Room, blank=True, null=True, default=None)
+ room = models.ForeignKey(Room, blank=True, null=True, default=None, on_delete=models.SET_NULL)
plenary = models.BooleanField(default=False)
materials = models.FileField(null=True, blank=True, upload_to=talks_materials_destination, verbose_name=_('Materials'),
help_text=_('You can use this field to share some materials related to your intervention.'))
video = models.URLField(max_length=1000, blank=True, default='', verbose_name='Video URL')
token = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
- conversation = models.OneToOneField(MessageThread)
+ conversation = models.OneToOneField(MessageThread, on_delete=models.PROTECT)
objects = TalkManager()
@@ -445,8 +445,8 @@ class Talk(PonyConfModel):
class Vote(PonyConfModel):
- talk = models.ForeignKey(Talk)
- user = models.ForeignKey(User)
+ talk = models.ForeignKey(Talk, on_delete=models.CASCADE)
+ user = models.ForeignKey(User, on_delete=models.CASCADE)
vote = models.IntegerField(validators=[MinValueValidator(-2), MaxValueValidator(2)], default=0)
class Meta:
@@ -491,7 +491,7 @@ class Volunteer(PonyConfModel):
notes = models.TextField(default='', blank=True, verbose_name=_('Notes'),
help_text=_('If you have some constraints, you can indicate them here.'))
activities = models.ManyToManyField(Activity, blank=True, related_name='volunteers', verbose_name=_('Activities'))
- conversation = models.OneToOneField(MessageThread)
+ conversation = models.OneToOneField(MessageThread, on_delete=models.PROTECT)
def get_absolute_url(self):
return reverse('volunteer-details', kwargs={'volunteer_id': self.pk})
diff --git a/cfp/planning.py b/cfp/planning.py
index a0268b2..24c55bb 100644
--- a/cfp/planning.py
+++ b/cfp/planning.py
@@ -3,7 +3,7 @@ from django.utils.safestring import mark_safe
from django.utils.html import escape
from django.utils.timezone import localtime, now
from django.core.cache import cache
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django.template.loader import get_template
from django.conf import settings
@@ -298,9 +298,9 @@ class Program:
if not result:
result = getattr(self, '_as_%s' % output)(**kwargs)
cache.set(cache_entry, result, 3 * 60 * 60) # 3H
- return mark_safe(result)
+ return result
else:
- return mark_safe(getattr(self, '_as_%s' % output)(**kwargs))
+ return getattr(self, '_as_%s' % output)(**kwargs)
def __str__(self):
return self.render()
diff --git a/cfp/signals.py b/cfp/signals.py
index b582901..57cb73c 100644
--- a/cfp/signals.py
+++ b/cfp/signals.py
@@ -4,7 +4,7 @@ from django.contrib.sites.models import Site
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django.contrib.auth import get_user_model
from ponyconf.decorators import disable_for_loaddata
diff --git a/cfp/templates/cfp/schedule.html b/cfp/templates/cfp/schedule.html
index 97c126d..8f9f528 100644
--- a/cfp/templates/cfp/schedule.html
+++ b/cfp/templates/cfp/schedule.html
@@ -8,6 +8,6 @@
{% trans "Schedule" %}
-{{ program }}
+{{ program|safe }}
{% endblock %}
diff --git a/cfp/templates/cfp/staff/schedule.html b/cfp/templates/cfp/staff/schedule.html
index dd3b5b9..e280b32 100644
--- a/cfp/templates/cfp/staff/schedule.html
+++ b/cfp/templates/cfp/staff/schedule.html
@@ -8,6 +8,6 @@
{% trans "Schedule" %}
-{{ program }}
+{{ program|safe }}
{% endblock %}
diff --git a/cfp/templates/cfp/staff/talk_details.html b/cfp/templates/cfp/staff/talk_details.html
index 635a869..7ab0848 100644
--- a/cfp/templates/cfp/staff/talk_details.html
+++ b/cfp/templates/cfp/staff/talk_details.html
@@ -88,11 +88,11 @@
{{ talk.vote_set.count }} {% trans "vote" %}{{ talk.vote_set.count|pluralize }}, {% trans "average:" %} {{ talk.score|floatformat:1 }}
diff --git a/cfp/tests.py b/cfp/tests.py
index 81a20bc..872aabf 100644
--- a/cfp/tests.py
+++ b/cfp/tests.py
@@ -1,6 +1,6 @@
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django.test import TestCase
from django.utils import timezone
from django.contrib import messages
@@ -148,11 +148,12 @@ class ProposalTest(TestCase):
conf.home = '**Welcome!**'
conf.save()
response = self.client.get(reverse('home'))
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Welcome!')
def test_proposal_closed(self):
conf = Conference.objects.get(name='PonyConf')
+ Talk.objects.filter(site=conf.site).all().delete()
TalkCategory.objects.filter(site=conf.site).all().delete()
response = self.client.get(reverse('proposal-home'))
self.assertEqual(response.status_code, 200)
@@ -190,7 +191,7 @@ class ProposalTest(TestCase):
'description': 'PonyConf is cool.',
})
speaker = Participant.objects.get(site=site, name='Jean-Mi')
- self.assertEquals(speaker.email, 'jean-mi@example.org')
+ self.assertEqual(speaker.email, 'jean-mi@example.org')
talk = Talk.objects.get(site=site, title='PonyConf')
self.assertRedirects(response, reverse('proposal-talk-details', kwargs=dict(speaker_token=speaker.token, talk_id=talk.pk)), 302)
self.assertTrue(speaker in talk.speakers.all())
@@ -211,9 +212,9 @@ class ProposalTest(TestCase):
'biography': 'New bio',
}), reverse('proposal-dashboard', kwargs={'speaker_token': speaker.token}))
speaker = Participant.objects.get(pk=speaker.pk)
- self.assertEquals(speaker.name, 'New name')
- self.assertEquals(speaker.email, 'new-mail@example.org')
- self.assertEquals(speaker.biography, 'New bio')
+ self.assertEqual(speaker.name, 'New name')
+ self.assertEqual(speaker.email, 'new-mail@example.org')
+ self.assertEqual(speaker.biography, 'New bio')
def test_proposal_talk_details(self):
speaker1 = Participant.objects.get(name='Speaker 1')
@@ -235,7 +236,7 @@ class ProposalTest(TestCase):
'description': 'Talk description',
})
talk = Talk.objects.get(title='New talk')
- self.assertEquals(talk.description, 'Talk description')
+ self.assertEqual(talk.description, 'Talk description')
self.assertRedirects(response, reverse('proposal-talk-details', kwargs=dict(speaker_token=speaker.token, talk_id=talk.pk)))
def test_proposal_talk_edit(self):
@@ -243,14 +244,14 @@ class ProposalTest(TestCase):
talk = Talk.objects.get(title='Talk 1')
url = reverse('proposal-talk-edit', kwargs={'speaker_token': speaker.token, 'talk_id': talk.pk})
response = self.client.get(url)
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
self.assertRedirects(self.client.post(url, {
'title': 'New title',
'description': 'New description',
}), reverse('proposal-talk-details', kwargs=dict(speaker_token=speaker.token, talk_id=talk.pk)))
talk = Talk.objects.get(pk=talk.pk)
- self.assertEquals(talk.title, 'New title')
- self.assertEquals(talk.description, 'New description')
+ self.assertEqual(talk.title, 'New title')
+ self.assertEqual(talk.description, 'New description')
def test_proposal_speaker_add(self):
speaker1 = Participant.objects.get(name='Speaker 1')
@@ -271,13 +272,13 @@ class ProposalTest(TestCase):
'notify': 1,
})
self.assertRedirects(response, url_talk)
- self.assertEquals(talk.speakers.count(), speaker_count+1)
+ self.assertEqual(talk.speakers.count(), speaker_count+1)
speaker5 = Participant.objects.get(name='Speaker 5')
self.assertTrue(speaker5 in talk.speakers.all())
self.assertFalse(speaker4 in talk.speakers.all())
response = self.client.get(url_add_existing)
self.assertRedirects(response, url_talk)
- self.assertEquals(talk.speakers.count(), speaker_count+2)
+ self.assertEqual(talk.speakers.count(), speaker_count+2)
self.assertTrue(speaker4 in talk.speakers.all())
@@ -334,11 +335,11 @@ class ProposalTest(TestCase):
talk.accepted = None
talk.save()
for url in [confirm_url, desist_url]:
- self.assertEquals(self.client.get(url).status_code, 403)
+ self.assertEqual(self.client.get(url).status_code, 403)
talk.accepted = False
talk.save()
for url in [confirm_url, desist_url]:
- self.assertEquals(self.client.get(url).status_code, 403)
+ self.assertEqual(self.client.get(url).status_code, 403)
talk.accepted = True
talk.save()
conf.save()
@@ -393,13 +394,13 @@ class StaffTest(TestCase):
url = reverse('staff')
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
- self.assertEquals(self.client.get(url).status_code, 200)
+ self.assertEqual(self.client.get(url).status_code, 200)
def test_admin(self):
url = reverse('admin')
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
- self.assertEquals(self.client.get(url).status_code, 200)
+ self.assertEqual(self.client.get(url).status_code, 200)
def test_volunteer_list(self):
url = reverse('volunteer-list')
@@ -431,14 +432,14 @@ class StaffTest(TestCase):
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
response = self.client.get(url)
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
def test_activity_add(self):
url = reverse('activity-list')
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
response = self.client.get(url)
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
def test_activity_edit(self):
conf = Conference.objects.get(name='PonyConf')
@@ -446,13 +447,13 @@ class StaffTest(TestCase):
url = reverse('activity-edit', kwargs={'slug': activity.slug})
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
- self.assertEquals(self.client.get(url).status_code, 200)
+ self.assertEqual(self.client.get(url).status_code, 200)
response = self.client.post(url, {
'name': 'New activity name',
})
self.assertRedirects(response, reverse('activity-list'))
activity = Activity.objects.get(pk=activity.pk)
- self.assertEquals(activity.name, 'New activity name')
+ self.assertEqual(activity.name, 'New activity name')
def test_activity_remove(self):
pass
@@ -462,7 +463,7 @@ class StaffTest(TestCase):
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
response = self.client.get(url)
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Speaker 1')
self.assertContains(response, 'Speaker 2')
response = self.client.get(url + '?format=csv')
@@ -478,7 +479,7 @@ class StaffTest(TestCase):
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
response = self.client.get(url)
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Speaker 1')
self.assertContains(response, 'Speaker 2')
self.assertNotContains(response, 'Speaker 3')
@@ -491,16 +492,16 @@ class StaffTest(TestCase):
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
response = self.client.get(url)
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
self.assertRedirects(self.client.post(url, {
'name': 'New name',
'email': 'new-mail@example.org',
'biography': 'New bio',
}), reverse('participant-details', kwargs={'participant_id': speaker.pk}))
speaker = Participant.objects.get(pk=speaker.pk)
- self.assertEquals(speaker.name, 'New name')
- self.assertEquals(speaker.email, 'new-mail@example.org')
- self.assertEquals(speaker.biography, 'New bio')
+ self.assertEqual(speaker.name, 'New name')
+ self.assertEqual(speaker.email, 'new-mail@example.org')
+ self.assertEqual(speaker.biography, 'New bio')
def test_speaker_add_talk(self):
speaker = Participant.objects.get(name='Speaker 1')
@@ -508,14 +509,14 @@ class StaffTest(TestCase):
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
response = self.client.get(url)
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
def test_talk_list(self):
url = reverse('talk-list')
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
response = self.client.get(url)
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Talk 1')
response = self.client.get(url + '?format=csv')
self.assertEqual(response.status_code, 200)
@@ -527,7 +528,7 @@ class StaffTest(TestCase):
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
response = self.client.get(url)
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
self.assertContains(response, talk.title)
def test_conference(self):
@@ -536,7 +537,7 @@ class StaffTest(TestCase):
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
response = self.client.get(url)
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
def test_conference_opened_categories(self):
# TODO cover all cases
@@ -618,7 +619,7 @@ class StaffTest(TestCase):
self.assertRedirects(self.client.get(accept_url), reverse('login') + '?next=' + accept_url)
self.assertRedirects(self.client.get(decline_url), reverse('login') + '?next=' + decline_url)
self.client.login(username='admin', password='admin')
- self.assertEquals(self.client.get(accept_url).status_code, 200)
+ self.assertEqual(self.client.get(accept_url).status_code, 200)
self.assertRedirects(self.client.post(accept_url), details_url)
talk = Talk.objects.get(pk=talk.pk)
self.assertTrue(talk.accepted)
@@ -627,7 +628,7 @@ class StaffTest(TestCase):
self.assertRedirects(self.client.post(accept_url, {'message': 'Ok'}), details_url)
talk = Talk.objects.get(pk=talk.pk)
self.assertTrue(talk.accepted)
- self.assertEquals(self.client.get(decline_url).status_code, 200)
+ self.assertEqual(self.client.get(decline_url).status_code, 200)
self.assertRedirects(self.client.post(decline_url), details_url)
talk = Talk.objects.get(pk=talk.pk)
self.assertFalse(talk.accepted)
@@ -648,50 +649,50 @@ class StaffTest(TestCase):
self.assertRedirects(self.client.get(confirm_url), reverse('login') + '?next=' + confirm_url)
self.assertRedirects(self.client.get(desist_url), reverse('login') + '?next=' + desist_url)
self.client.login(username='admin', password='admin')
- self.assertEquals(self.client.get(confirm_url).status_code, 403)
- self.assertEquals(self.client.get(desist_url).status_code, 403)
+ self.assertEqual(self.client.get(confirm_url).status_code, 403)
+ self.assertEqual(self.client.get(desist_url).status_code, 403)
talk.accepted = False
talk.save()
- self.assertEquals(self.client.get(confirm_url).status_code, 403)
- self.assertEquals(self.client.get(desist_url).status_code, 403)
+ self.assertEqual(self.client.get(confirm_url).status_code, 403)
+ self.assertEqual(self.client.get(desist_url).status_code, 403)
talk.accepted = True
talk.save()
self.assertRedirects(self.client.get(confirm_url), details_url)
talk = Talk.objects.get(pk=talk.pk)
self.assertTrue(talk.confirmed)
- self.assertEquals(self.client.get(confirm_url).status_code, 403)
+ self.assertEqual(self.client.get(confirm_url).status_code, 403)
self.assertRedirects(self.client.get(desist_url), details_url)
talk = Talk.objects.get(pk=talk.pk)
self.assertFalse(talk.confirmed)
- self.assertEquals(self.client.get(desist_url).status_code, 403)
+ self.assertEqual(self.client.get(desist_url).status_code, 403)
def test_category_list(self):
url = reverse('category-list')
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
response = self.client.get(url)
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
def test_category_add(self):
url = reverse('category-add')
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
response = self.client.get(url)
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
def test_tag_list(self):
url = reverse('tag-list')
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
response = self.client.get(url)
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
def test_tag_add(self):
url = reverse('tag-add')
self.assertRedirects(self.client.get(url), reverse('login') + '?next=' + url)
self.client.login(username='admin', password='admin')
response = self.client.get(url)
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
class ScheduleTest(TestCase):
@@ -719,10 +720,10 @@ class ScheduleTest(TestCase):
def test_public_schedule(self):
site = Site.objects.first()
conf = Conference.objects.get(site=site)
- self.assertEquals(self.client.get(reverse('public-schedule')).status_code, 403)
+ self.assertEqual(self.client.get(reverse('public-schedule')).status_code, 403)
conf.schedule_publishing_date = timezone.now() - timedelta(hours=1)
conf.save()
- self.assertEquals(self.client.get(reverse('public-schedule')).status_code, 200)
+ self.assertEqual(self.client.get(reverse('public-schedule')).status_code, 200)
conf.schedule_redirection_url ='http://example.net/schedule.html'
conf.save()
self.assertRedirects(self.client.get(reverse('public-schedule')), conf.schedule_redirection_url, status_code=302, fetch_redirect_response=False)
@@ -735,7 +736,7 @@ class ScheduleTest(TestCase):
def test_xml(self):
self.client.login(username='admin', password='admin')
response = self.client.get(reverse('staff-schedule') + 'xml/')
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Public tag')
self.assertNotContains(response, 'Private tag')
ET.fromstring(response.content)
@@ -743,7 +744,7 @@ class ScheduleTest(TestCase):
def test_ics(self):
self.client.login(username='admin', password='admin')
response = self.client.get(reverse('staff-schedule') + 'ics/')
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
Calendar.from_ical(response.content)
def test_html(self):
@@ -751,8 +752,8 @@ class ScheduleTest(TestCase):
response = self.client.get(reverse('staff-schedule') + 'html/')
self.assertContains(response, 'Staff tag')
self.assertNotContains(response, 'Not staff tag')
- self.assertEquals(response.status_code, 200)
+ self.assertEqual(response.status_code, 200)
def test_inexistent_format(self):
self.client.login(username='admin', password='admin')
- self.assertEquals(self.client.get(reverse('staff-schedule') + 'inexistent/').status_code, 404)
+ self.assertEqual(self.client.get(reverse('staff-schedule') + 'inexistent/').status_code, 404)
diff --git a/cfp/urls.py b/cfp/urls.py
index 64b8bd3..c676c01 100644
--- a/cfp/urls.py
+++ b/cfp/urls.py
@@ -1,70 +1,71 @@
-from django.conf.urls import url
+from django.urls import path, re_path, register_converter
+
+from . import views, converters
+
+
+register_converter(converters.SignedIntConverter, 'sint')
-from . import views
urlpatterns = [
- url(r'^$', views.home, name='home'),
-# v1.1
- url(r'^cfp/$', views.proposal_home, name='proposal-home'),
- url(r'^cfp/token/$', views.proposal_mail_token, name='proposal-mail-token'),
- url(r'^cfp/(?:(?P[\w\-]+)/)?dashboard/$', views.proposal_dashboard, name='proposal-dashboard'),
- url(r'^cfp/(?:(?P[\w\-]+)/)?profile/$', views.proposal_speaker_edit, name='proposal-profile-edit'),
- url(r'^cfp/(?:(?P[\w\-]+)/)?talk/add/$', views.proposal_talk_edit, name='proposal-talk-add'),
- url(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/$', views.proposal_talk_details, name='proposal-talk-details'),
- url(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/edit/$', views.proposal_talk_edit, name='proposal-talk-edit'),
- url(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/speaker/add/$', views.proposal_speaker_edit, name='proposal-speaker-add'),
- url(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/speaker/add/(?P[0-9]+)/$', views.proposal_speaker_add, name='proposal-speaker-add-existing'),
- #url(r'^cfp(?:/(?P[\w\-]+))?/talk/(?P[0-9]+)/speaker/(?P[0-9]+)/$', views.proposal_speaker_details, name='proposal-speaker-details'),
- url(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/speaker/(?P[0-9]+)/edit/$', views.proposal_speaker_edit, name='proposal-speaker-edit'),
- url(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/speaker/(?P[0-9]+)/remove/$', views.proposal_speaker_remove, name='proposal-speaker-remove'),
- url(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/confirm/$', views.proposal_talk_acknowledgment, {'confirm': True}, name='proposal-talk-confirm'),
- url(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/desist/$', views.proposal_talk_acknowledgment, {'confirm': False}, name='proposal-talk-desist'),
- url(r'^volunteer/enrole/$', views.volunteer_enrole, name='volunteer-enrole'),
- url(r'^volunteer/token/$', views.volunteer_mail_token, name='volunteer-mail-token'),
- url(r'^volunteer/(?:(?P[\w\-]+)/)?$', views.volunteer_dashboard, name='volunteer-dashboard'),
- url(r'^volunteer/(?:(?P[\w\-]+)/)?profile/$', views.volunteer_profile, name='volunteer-profile-edit'),
- url(r'^volunteer/(?:(?P[\w\-]+)/)?join/(?P[\w\-]+)/$', views.volunteer_update_activity, {'join': True}, name='volunteer-join'),
- url(r'^volunteer/(?:(?P[\w\-]+)/)?quit/(?P[\w\-]+)/$', views.volunteer_update_activity, {'join': False}, name='volunteer-quit'),
- #url(r'^talk/(?P[\w\-]+)/$', views.talk_show, name='show-talk'),
- #url(r'^speaker/(?P[\w\-]+)/$', views.speaker_show, name='show-speaker'),
- url(r'^staff/$', views.staff, name='staff'),
- url(r'^staff/talks/$', views.talk_list, name='talk-list'),
- url(r'^staff/talks/(?P[0-9]+)/$', views.talk_details, name='talk-details'),
- url(r'^staff/talks/(?P[0-9]+)/vote/(?P[-+0-2]+)/$', views.talk_vote, name='talk-vote'),
- url(r'^staff/talks/(?P[0-9]+)/accept/$', views.talk_decide, {'accept': True}, name='talk-accept'),
- url(r'^staff/talks/(?P[0-9]+)/decline/$', views.talk_decide, {'accept': False}, name='talk-decline'),
- url(r'^staff/talks/(?P[0-9]+)/confirm/$', views.talk_acknowledgment, {'confirm': True}, name='talk-confirm-by-staff'),
- url(r'^staff/talks/(?P[0-9]+)/desist/$', views.talk_acknowledgment, {'confirm': False}, name='talk-desist-by-staff'),
- url(r'^staff/talks/(?P[0-9]+)/edit/$', views.TalkUpdate.as_view(), name='talk-edit'),
- url(r'^staff/speakers/$', views.participant_list, name='participant-list'),
- url(r'^staff/speakers/add/$', views.ParticipantCreate.as_view(), name='participant-add'),
- url(r'^staff/speakers/(?P[0-9]+)/$', views.participant_details, name='participant-details'),
- url(r'^staff/speakers/(?P[0-9]+)/add-talk/$', views.participant_add_talk, name='participant-add-talk'),
- url(r'^staff/speakers/(?P[0-9]+)/edit/$', views.ParticipantUpdate.as_view(), name='participant-edit'),
- url(r'^staff/speakers/(?P[0-9]+)/remove/$', views.ParticipantRemove.as_view(), name='participant-remove'),
- url(r'^staff/tracks/$', views.TrackList.as_view(), name='track-list'),
- url(r'^staff/tracks/add/$', views.TrackCreate.as_view(), name='track-add'),
- url(r'^staff/tracks/(?P[-\w]+)/edit/$', views.TrackUpdate.as_view(), name='track-edit'),
- url(r'^staff/rooms/$', views.RoomList.as_view(), name='room-list'),
- url(r'^staff/rooms/add/$', views.RoomCreate.as_view(), name='room-add'),
- url(r'^staff/rooms/(?P[-\w]+)/$', views.RoomDetail.as_view(), name='room-details'),
- url(r'^staff/rooms/(?P[-\w]+)/edit/$', views.RoomUpdate.as_view(), name='room-edit'),
- url(r'^staff/volunteers/$', views.volunteer_list, name='volunteer-list'),
- url(r'^staff/volunteers/(?P[\w\-]+)/$', views.volunteer_details, name='volunteer-details'),
- url(r'^staff/add-user/$', views.create_user, name='create-user'),
- url(r'^staff/schedule/((?P[\w]+)/)?$', views.staff_schedule, name='staff-schedule'),
- url(r'^staff/select2/$', views.Select2View.as_view(), name='django_select2-json'),
- url(r'^admin/$', views.admin, name='admin'),
- url(r'^admin/conference/$', views.conference_edit, name='conference-edit'),
- url(r'^admin/homepage/$', views.homepage_edit, name='homepage-edit'),
- url(r'^admin/categories/$', views.TalkCategoryList.as_view(), name='category-list'),
- url(r'^admin/categories/add/$', views.TalkCategoryCreate.as_view(), name='category-add'),
- url(r'^admin/categories/(?P[0-9]+)/edit/$', views.TalkCategoryUpdate.as_view(), name='category-edit'),
- url(r'^admin/tags/$', views.TagList.as_view(), name='tag-list'),
- url(r'^admin/tags/add/$', views.TagCreate.as_view(), name='tag-add'),
- url(r'^admin/tags/(?P[-\w]+)/edit/$', views.TagUpdate.as_view(), name='tag-edit'),
- url(r'^admin/activities/$', views.ActivityList.as_view(), name='activity-list'),
- url(r'^admin/activities/add/$', views.ActivityCreate.as_view(), name='activity-add'),
- url(r'^admin/activities/(?P[-\w]+)/edit/$', views.ActivityUpdate.as_view(), name='activity-edit'),
- url(r'^schedule/((?P[\w]+)/)?$', views.public_schedule, name='public-schedule'),
+ path('', views.home, name='home'),
+ path('cfp/', views.proposal_home, name='proposal-home'),
+ path('cfp/token/', views.proposal_mail_token, name='proposal-mail-token'),
+ re_path(r'^cfp/(?:(?P[\w\-]+)/)?dashboard/$', views.proposal_dashboard, name='proposal-dashboard'),
+ re_path(r'^cfp/(?:(?P[\w\-]+)/)?profile/$', views.proposal_speaker_edit, name='proposal-profile-edit'),
+ re_path(r'^cfp/(?:(?P[\w\-]+)/)?talk/add/$', views.proposal_talk_edit, name='proposal-talk-add'),
+ re_path(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/$', views.proposal_talk_details, name='proposal-talk-details'),
+ re_path(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/edit/$', views.proposal_talk_edit, name='proposal-talk-edit'),
+ re_path(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/speaker/add/$', views.proposal_speaker_edit, name='proposal-speaker-add'),
+ re_path(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/speaker/add/(?P[0-9]+)/$', views.proposal_speaker_add, name='proposal-speaker-add-existing'),
+ #re_path(r'^cfp(?:/(?P[\w\-]+))?/talk/(?P[0-9]+)/speaker/(?P[0-9]+)/$', views.proposal_speaker_details, name='proposal-speaker-details'),
+ re_path(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/speaker/(?P[0-9]+)/edit/$', views.proposal_speaker_edit, name='proposal-speaker-edit'),
+ re_path(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/speaker/(?P[0-9]+)/remove/$', views.proposal_speaker_remove, name='proposal-speaker-remove'),
+ re_path(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/confirm/$', views.proposal_talk_acknowledgment, {'confirm': True}, name='proposal-talk-confirm'),
+ re_path(r'^cfp/(?:(?P[\w\-]+)/)?talk/(?P[0-9]+)/desist/$', views.proposal_talk_acknowledgment, {'confirm': False}, name='proposal-talk-desist'),
+ path('volunteer/enrole', views.volunteer_enrole, name='volunteer-enrole'),
+ path('volunteer/token/', views.volunteer_mail_token, name='volunteer-mail-token'),
+ re_path(r'^volunteer/(?:(?P[\w\-]+)/)?$', views.volunteer_dashboard, name='volunteer-dashboard'),
+ re_path(r'^volunteer/(?:(?P[\w\-]+)/)?profile/$', views.volunteer_profile, name='volunteer-profile-edit'),
+ re_path(r'^volunteer/(?:(?P[\w\-]+)/)?join/(?P[\w\-]+)/$', views.volunteer_update_activity, {'join': True}, name='volunteer-join'),
+ re_path(r'^volunteer/(?:(?P[\w\-]+)/)?quit/(?P[\w\-]+)/$', views.volunteer_update_activity, {'join': False}, name='volunteer-quit'),
+ path('staff/', views.staff, name='staff'),
+ path('staff/talks/', views.talk_list, name='talk-list'),
+ path('staff/talks//', views.talk_details, name='talk-details'),
+ path('staff/talks//vote//', views.talk_vote, name='talk-vote'),
+ path('staff/talks//accept/', views.talk_decide, {'accept': True}, name='talk-accept'),
+ path('staff/talks//decline/', views.talk_decide, {'accept': False}, name='talk-decline'),
+ path('staff/talks//confirm/', views.talk_acknowledgment, {'confirm': True}, name='talk-confirm-by-staff'),
+ path('staff/talks//desist/', views.talk_acknowledgment, {'confirm': False}, name='talk-desist-by-staff'),
+ path('staff/talks//edit/', views.TalkUpdate.as_view(), name='talk-edit'),
+ path('staff/speakers/', views.participant_list, name='participant-list'),
+ path('staff/speakers/add/', views.ParticipantCreate.as_view(), name='participant-add'),
+ path('staff/speakers//', views.participant_details, name='participant-details'),
+ path('staff/speakers//add-talk/', views.participant_add_talk, name='participant-add-talk'),
+ path('staff/speakers//edit/', views.ParticipantUpdate.as_view(), name='participant-edit'),
+ path('staff/speakers//remove/', views.ParticipantRemove.as_view(), name='participant-remove'),
+ path('staff/tracks/', views.TrackList.as_view(), name='track-list'),
+ path('staff/tracks/add/', views.TrackCreate.as_view(), name='track-add'),
+ path('staff/tracks//edit/', views.TrackUpdate.as_view(), name='track-edit'),
+ path('staff/rooms/', views.RoomList.as_view(), name='room-list'),
+ path('staff/rooms/add/', views.RoomCreate.as_view(), name='room-add'),
+ path('staff/rooms//', views.RoomDetail.as_view(), name='room-details'),
+ path('staff/rooms//edit/', views.RoomUpdate.as_view(), name='room-edit'),
+ path('staff/volunteers/', views.volunteer_list, name='volunteer-list'),
+ path('staff/volunteers//', views.volunteer_details, name='volunteer-details'),
+ path('staff/add-user/', views.create_user, name='create-user'),
+ re_path(r'^staff/schedule/((?P[\w]+)/)?$', views.staff_schedule, name='staff-schedule'),
+ path('staff/select2/', views.Select2View.as_view(), name='django_select2-json'),
+ path('admin/', views.admin, name='admin'),
+ path('admin/conference/', views.conference_edit, name='conference-edit'),
+ path('admin/homepage/', views.homepage_edit, name='homepage-edit'),
+ path('admin/categories/', views.TalkCategoryList.as_view(), name='category-list'),
+ path('admin/categories/add/', views.TalkCategoryCreate.as_view(), name='category-add'),
+ path('admin/categories//edit/', views.TalkCategoryUpdate.as_view(), name='category-edit'),
+ path('admin/tags/', views.TagList.as_view(), name='tag-list'),
+ path('admin/tags/add/', views.TagCreate.as_view(), name='tag-add'),
+ path('admin/tags//edit/', views.TagUpdate.as_view(), name='tag-edit'),
+ path('admin/activities/', views.ActivityList.as_view(), name='activity-list'),
+ path('admin/activities/add/', views.ActivityCreate.as_view(), name='activity-add'),
+ path('admin/activities//edit/', views.ActivityUpdate.as_view(), name='activity-edit'),
+ re_path(r'^schedule/((?P[\w]+)/)?$', views.public_schedule, name='public-schedule'),
]
diff --git a/cfp/views.py b/cfp/views.py
index 1f46a48..d1c8854 100644
--- a/cfp/views.py
+++ b/cfp/views.py
@@ -1,8 +1,7 @@
from django.core.mail import send_mail
-from django.core.urlresolvers import reverse_lazy
from django.shortcuts import get_object_or_404, redirect, render
from django.template.loader import render_to_string
-from django.urls import reverse
+from django.urls import reverse, reverse_lazy
from django.utils.translation import ugettext_lazy as _
from django.views.generic import DeleteView, FormView, TemplateView
from django.contrib import messages
@@ -42,24 +41,24 @@ def home(request):
def volunteer_enrole(request):
- if request.user.is_authenticated() and Volunteer.objects.filter(site=request.conference.site, email=request.user.email).exists():
+ if request.user.is_authenticated and Volunteer.objects.filter(site=request.conference.site, email=request.user.email).exists():
return redirect(reverse('volunteer-dashboard'))
if not request.conference.volunteers_enrollment_is_open():
raise PermissionDenied
initial = {}
- if request.user.is_authenticated() and not request.POST:
+ if request.user.is_authenticated and not request.POST:
initial.update({
'name': request.user.get_full_name(),
'phone_number': request.user.profile.phone_number,
'sms_prefered': request.user.profile.sms_prefered,
})
form = VolunteerForm(request.POST or None, initial=initial, conference=request.conference)
- if request.user.is_authenticated():
+ if request.user.is_authenticated:
form.fields.pop('email')
if request.method == 'POST' and form.is_valid():
volunteer = form.save(commit=False)
volunteer.language = request.LANGUAGE_CODE
- if request.user.is_authenticated():
+ if request.user.is_authenticated:
volunteer.email = request.user.email
volunteer.save()
form.save_m2m()
@@ -205,7 +204,7 @@ def proposal_home(request):
return render(request, 'cfp/closed.html')
initial = {}
fields = ['name', 'email', 'biography']
- if request.user.is_authenticated():
+ if request.user.is_authenticated:
if Participant.objects.filter(site=request.conference.site, email=request.user.email).exists():
return redirect(reverse('proposal-dashboard'))
elif not request.POST:
@@ -220,7 +219,7 @@ def proposal_home(request):
if request.method == 'POST' and all(map(lambda f: f.is_valid(), [speaker_form, talk_form])):
speaker = speaker_form.save(commit=False)
speaker.site = request.conference.site
- if request.user.is_authenticated():
+ if request.user.is_authenticated:
speaker.email = request.user.email
speaker.save()
talk = talk_form.save(commit=False)
@@ -725,9 +724,11 @@ def talk_details(request, talk_id):
@staff_required
def talk_vote(request, talk_id, score):
+ if score not in [-2, -1, 0, 1, 2]:
+ raise Http404
talk = get_object_or_404(Talk, pk=talk_id, site=request.conference.site)
vote, created = Vote.objects.get_or_create(talk=talk, user=request.user)
- vote.vote = int(score)
+ vote.vote = score
vote.save()
messages.success(request, _('Vote successfully created') if created else _('Vote successfully updated'))
return redirect(talk.get_absolute_url())
diff --git a/mailing/models.py b/mailing/models.py
index 82a6455..3d023a4 100644
--- a/mailing/models.py
+++ b/mailing/models.py
@@ -56,9 +56,9 @@ class MessageManager(models.Manager):
class Message(models.Model):
created = models.DateTimeField(auto_now_add=True)
- thread = models.ForeignKey(MessageThread)
- author = models.ForeignKey(MessageAuthor)
- in_reply_to = models.ForeignKey('self', null=True, blank=True)
+ thread = models.ForeignKey(MessageThread, on_delete=models.CASCADE)
+ author = models.ForeignKey(MessageAuthor, on_delete=models.PROTECT)
+ in_reply_to = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL)
subject = models.CharField(max_length=1000, blank=True)
content = models.TextField(blank=True)
token = models.CharField(max_length=64, default=generate_message_token, unique=True)
diff --git a/mailing/tests.py b/mailing/tests.py
index 5b67ee3..0922f0e 100644
--- a/mailing/tests.py
+++ b/mailing/tests.py
@@ -1,6 +1,6 @@
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django.test import TestCase, override_settings
from django.core import mail
from django.conf import settings
diff --git a/ponyconf/settings.py b/ponyconf/settings.py
index 49ceca3..8fd694c 100644
--- a/ponyconf/settings.py
+++ b/ponyconf/settings.py
@@ -66,7 +66,6 @@ MIDDLEWARE = [
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
diff --git a/ponyconf/urls.py b/ponyconf/urls.py
index 2b7f5c2..facaabb 100644
--- a/ponyconf/urls.py
+++ b/ponyconf/urls.py
@@ -1,19 +1,4 @@
-"""ponyconf URL Configuration
-
-The `urlpatterns` list routes URLs to views. For more information please see:
- https://docs.djangoproject.com/en/1.9/topics/http/urls/
-Examples:
-Function views
- 1. Add an import: from my_app import views
- 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
-Class-based views
- 1. Add an import: from other_app.views import Home
- 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
-Including another URLconf
- 1. Import the include() function: from django.conf.urls import url, include
- 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
-"""
-from django.conf.urls import include, url
+from django.urls import include, path
from django.contrib import admin
from django.conf import settings
@@ -21,14 +6,14 @@ from . import views
urlpatterns = [
- url(r'^markdown/$', views.markdown_preview, name='markdown-preview'),
- url(r'^admin/django/', admin.site.urls),
- url(r'^accounts/', include('accounts.urls')),
- url(r'^', include('cfp.urls')),
+ path('markdown/', views.markdown_preview, name='markdown-preview'),
+ path('admin/django/', admin.site.urls),
+ path('accounts/', include('accounts.urls')),
+ path('', include('cfp.urls')),
]
if settings.DEBUG and 'debug_toolbar' in settings.INSTALLED_APPS:
import debug_toolbar
urlpatterns += [
- url(r'^__debug__/', include(debug_toolbar.urls)),
+ path('__debug__/', include(debug_toolbar.urls)),
]
diff --git a/requirements.in b/requirements.in
index fba7670..a1a51ed 100644
--- a/requirements.in
+++ b/requirements.in
@@ -1,11 +1,11 @@
-django<1.12
+django<3
-django-autoslug
django-bootstrap3
django-bower
django-crispy-forms
django-select2<6
django-colorful
+-e git://github.com/nim65s/django-autoslug.git#egg=django-autoslug
markdown
bleach
diff --git a/requirements.txt b/requirements.txt
index db92898..4f7397d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,19 +4,19 @@
#
# pip-compile --output-file requirements.txt requirements.in
#
-bleach==2.1.1
+-e git+git://github.com/nim65s/django-autoslug.git#egg=django-autoslug
+bleach==2.1.2
chardet==3.0.4
django-appconf==1.0.2 # via django-select2
-django-autoslug==1.9.3
django-bootstrap3==9.1.0
django-bower==5.2.0
django-colorful==1.2
django-crispy-forms==1.7.0
django-select2==5.11.1
-django==1.11.7
-html5lib==1.0b10 # via bleach
+django==2.0
+html5lib==1.0.1 # via bleach
icalendar==4.0.0
-markdown==2.6.9
+markdown==2.6.10
python-dateutil==2.6.1 # via icalendar
pytz==2017.3 # via django, icalendar
six==1.11.0 # via bleach, django-bower, html5lib, python-dateutil