diff --git a/accounts/mixins.py b/accounts/mixins.py index d1a5689..bc70111 100644 --- a/accounts/mixins.py +++ b/accounts/mixins.py @@ -1,18 +1,8 @@ from django.contrib.auth.mixins import UserPassesTestMixin -from .utils import is_orga, is_staff - - -class OrgaRequiredMixin(UserPassesTestMixin): - def test_func(self): - return is_orga(self.request, self.request.user) +from .utils import is_staff class StaffRequiredMixin(UserPassesTestMixin): def test_func(self): return is_staff(self.request, self.request.user) - - -class SuperuserRequiredMixin(UserPassesTestMixin): - def test_func(self): - return self.request.user.is_superuser diff --git a/cfp/forms.py b/cfp/forms.py index 39249af..ce36d02 100644 --- a/cfp/forms.py +++ b/cfp/forms.py @@ -1,7 +1,11 @@ from django import forms from django.forms.models import modelform_factory +from django.contrib.auth.admin import UserAdmin +from django.contrib.auth.models import User -from .models import Participant, Talk +from django_select2.forms import ModelSelect2MultipleWidget + +from .models import Participant, Talk, Conference class TalkForm(forms.ModelForm): @@ -19,3 +23,11 @@ class TalkForm(forms.ModelForm): ParticipantForm = modelform_factory(Participant, fields=('name','email', 'biography')) + + +class UsersWidget(ModelSelect2MultipleWidget): + model = User + search_fields = [ '%s__icontains' % field for field in UserAdmin.search_fields ] + + +ConferenceForm = modelform_factory(Conference, fields=['name', 'home', 'venue', 'city', 'contact_email', 'staff',], widgets={'staff': UsersWidget(),}) diff --git a/cfp/mixins.py b/cfp/mixins.py new file mode 100644 index 0000000..bc70111 --- /dev/null +++ b/cfp/mixins.py @@ -0,0 +1,8 @@ +from django.contrib.auth.mixins import UserPassesTestMixin + +from .utils import is_staff + + +class StaffRequiredMixin(UserPassesTestMixin): + def test_func(self): + return is_staff(self.request, self.request.user) diff --git a/cfp/models.py b/cfp/models.py index 514f49e..3edbcab 100644 --- a/cfp/models.py +++ b/cfp/models.py @@ -33,12 +33,12 @@ from django.utils.translation import ugettext class Conference(models.Model): site = models.OneToOneField(Site, on_delete=models.CASCADE) - name = models.CharField(blank=True, max_length=100) - home = models.TextField(blank=True, default="") - venue = models.TextField(blank=True, default="") - city = models.CharField(max_length=64, blank=True, default="") - contact_email = models.CharField(max_length=100, blank=True) - staff = models.ManyToManyField(User, verbose_name=_('Staff'), blank=True) + name = models.CharField(blank=True, max_length=100, verbose_name=_('Conference name')) + home = models.TextField(blank=True, default="", verbose_name=_('Homepage (markdown)')) + venue = models.TextField(blank=True, default="", verbose_name=_('Venue information')) + city = models.CharField(max_length=64, blank=True, default="", verbose_name=_('City')) + contact_email = models.CharField(max_length=100, blank=True, verbose_name=_('Contact email')) + staff = models.ManyToManyField(User, blank=True, verbose_name=_('Staff members')) custom_css = models.TextField(blank=True) external_css_link = models.URLField(blank=True) diff --git a/cfp/templates/cfp/staff/base.html b/cfp/templates/cfp/staff/base.html index e16abdc..dcf58f2 100644 --- a/cfp/templates/cfp/staff/base.html +++ b/cfp/templates/cfp/staff/base.html @@ -17,6 +17,7 @@ {% endcomment %}  {% trans "Talks" %}  {% trans "Speakers" %} +  {% trans "Conference" %} {% if request.user.is_staff %}
  •  Django-Admin
  • {% endif %} diff --git a/cfp/templates/cfp/staff/conference.html b/cfp/templates/cfp/staff/conference.html new file mode 100644 index 0000000..a336cb9 --- /dev/null +++ b/cfp/templates/cfp/staff/conference.html @@ -0,0 +1,26 @@ +{% extends 'cfp/staff/base.html' %} +{% load i18n crispy_forms_tags %} + +{% block conferencetab %} class="active"{% endblock %} + +{% block content %} + +

    {% trans "Conference" %}

    + +
    + {% csrf_token %} + {{ form|crispy }} + +
    + +{% endblock %} + +{% block js_end %} +{{ block.super }} +{{ form.media.js }} +{% endblock %} + +{% block css %} +{{ block.super }} +{{ form.media.css }} +{% endblock %} diff --git a/cfp/urls.py b/cfp/urls.py index 418d1dd..5cad1d3 100644 --- a/cfp/urls.py +++ b/cfp/urls.py @@ -9,6 +9,7 @@ urlpatterns = [ url(r'^cfp/(?P[\w\-]+)/speaker/(?P[\w\-]+)/$', views.talk_proposal_speaker_edit, name='talk-proposal-speaker-edit'), url(r'^cfp/(?P[\w\-]+)/(?P[\w\-]+)/$', views.talk_proposal, name='talk-proposal-edit'), url(r'^staff/$', views.staff, name='staff'), + url(r'^staff/conference/$', views.conference, name='conference'), url(r'^staff/talks/$', views.talk_list, name='talk-list'), url(r'^staff/talks/(?P[\w\-]+)/$', views.talk_details, name='talk-details'), url(r'^staff/talks/(?P[\w\-]+)/vote/(?P[-+0-2]+)/$', views.talk_vote, name='talk-vote'), @@ -16,6 +17,7 @@ urlpatterns = [ url(r'^staff/talks/(?P[\w\-]+)/decline/$', views.talk_decide, {'accept': False}, name='talk-decline'), url(r'^staff/speakers/$', views.participant_list, name='participant-list'), url(r'^staff/speakers/(?P[\w\-]+)/$', views.participant_details, name='participant-details'), + url(r'^staff/select2/$', views.Select2View.as_view(), name='django_select2-json'), #url(r'^markdown/$', views.markdown_preview, name='markdown'), #url(r'^$', views.home, name='home'), diff --git a/cfp/views.py b/cfp/views.py index 181504e..22f0fab 100644 --- a/cfp/views.py +++ b/cfp/views.py @@ -6,10 +6,13 @@ from django.utils.translation import ugettext_lazy as _ from django.views.generic import FormView, TemplateView from django.contrib import messages +from django_select2.views import AutoResponseView + from cfp.decorators import staff_required +from .mixins import StaffRequiredMixin from .utils import is_staff from .models import Participant, Talk, TalkCategory, Vote -from .forms import TalkForm, ParticipantForm +from .forms import TalkForm, ParticipantForm, ConferenceForm def home(request, conference): @@ -193,3 +196,21 @@ def participant_details(request, conference, participant_id): return render(request, 'cfp/staff/participant_details.html', { 'participant': participant, }) + + +@staff_required +def conference(request, conference): + form = ConferenceForm(request.POST or None, instance=conference) + + if request.method == 'POST' and form.is_valid(): + form.save() + messages.success(request, _('Modifications successfully saved.')) + return redirect(reverse('conference')) + + return render(request, 'cfp/staff/conference.html', { + 'form': form, + }) + + +class Select2View(StaffRequiredMixin, AutoResponseView): + pass diff --git a/locale/fr/LC_MESSAGES/django.mo b/locale/fr/LC_MESSAGES/django.mo index f5350e0..5d68ec2 100644 Binary files a/locale/fr/LC_MESSAGES/django.mo and b/locale/fr/LC_MESSAGES/django.mo differ diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index e89780a..e8c8006 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-07-30 14:00+0000\n" +"POT-Creation-Date: 2017-07-30 18:07+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -106,7 +106,7 @@ msgstr "Biographie" #: accounts/templates/accounts/participant_details.html:27 #: cfp/templates/cfp/staff/base.html:20 -#: cfp/templates/cfp/staff/participant_details.html:32 +#: cfp/templates/cfp/staff/participant_details.html:31 #: cfp/templates/cfp/staff/talk_list.html:8 #: proposals/templates/proposals/talk_list.html:9 msgid "Talks" @@ -173,7 +173,7 @@ msgid "Constraints" msgstr "Contraintes" #: accounts/templates/accounts/participant_details.html:71 cfp/models.py:87 -#: cfp/templates/cfp/staff/participant_details.html:27 +#: cfp/templates/cfp/staff/participant_details.html:14 #: cfp/templates/cfp/staff/talk_details.html:92 proposals/models.py:161 #: proposals/templates/proposals/talk_detail.html:102 msgid "Notes" @@ -214,7 +214,8 @@ msgstr "Changer d’avatar" msgid "Submit" msgstr "Envoyer" -#: accounts/templates/accounts/profile.html:36 ponyconf/templates/_form.html:16 +#: accounts/templates/accounts/profile.html:36 +#: cfp/templates/cfp/staff/talk_decide.html:27 ponyconf/templates/_form.html:16 #: proposals/templates/proposals/talk_decide.html:23 msgid "Cancel" msgstr "Annuler" @@ -286,15 +287,35 @@ msgstr "%(name)s a été ajouté aux participants" msgid "%(name)s is already a participant" msgstr "%(name)s est déjà participant" -#: cfp/models.py:41 ponyconf/templates/base.html:36 -msgid "Staff" -msgstr "" +#: cfp/models.py:36 +msgid "Conference name" +msgstr "Nom de la conférence" + +#: cfp/models.py:37 +msgid "Homepage (markdown)" +msgstr "Page d’accueil (markdown)" + +#: cfp/models.py:38 +msgid "Venue information" +msgstr "Informations sur le lieu" + +#: cfp/models.py:39 +msgid "City" +msgstr "Ville" + +#: cfp/models.py:40 +msgid "Contact email" +msgstr "Email de contact" + +#: cfp/models.py:41 +msgid "Staff members" +msgstr "Membres du staff" #: cfp/models.py:70 msgid "Your Name" msgstr "Votre Nom" -#: cfp/models.py:87 cfp/templates/cfp/staff/participant_details.html:28 +#: cfp/models.py:87 msgid "This field is only visible by organizers." msgstr "Ce champs est uniquement visible par les organisateurs." @@ -383,9 +404,19 @@ msgstr "J’ai besoin de son" msgid "Duration (min)" msgstr "Durée (min)" +#: cfp/templates/cfp/closed.html:9 cfp/templates/cfp/propose.html:11 +#: cfp/templates/cfp/speaker.html:11 +#: proposals/templates/proposals/participate.html:9 +msgid "Participate" +msgstr "Participer" + +#: cfp/templates/cfp/closed.html:13 +msgid "Sorry, the Call for Participation is closed!" +msgstr "Désolé, l’appel à participation est fermé." + #: cfp/templates/cfp/complete.html:10 msgid "Your proposition have been successfully submitted!" -msgstr "Votre proposition a été transmise avec succès!" +msgstr "Votre proposition a été transmise avec succès !" #: cfp/templates/cfp/complete.html:16 msgid "Thanks for your proposal" @@ -393,83 +424,84 @@ msgstr "Merci pour votre proposition" #: cfp/templates/cfp/complete.html:17 msgid "You can at anytime:" -msgstr "Vous pouvez à tout moment:" +msgstr "Vous pouvez à tout moment :" #: cfp/templates/cfp/complete.html:19 msgid "Edit your talk:" msgstr "Éditer un exposé" #: cfp/templates/cfp/complete.html:20 -msgid "add an additionnal speaker:" -msgstr "ajouter un co-speaker:" +msgid "Add an additionnal speaker:" +msgstr "Ajouter un co-speaker :" #: cfp/templates/cfp/complete.html:21 -msgid "You can edit your profile:" -msgstr "Vous pouvez éditer votre profil:" +msgid "Edit your profile:" +msgstr "Éditer votre profil :" #: cfp/templates/cfp/complete.html:24 msgid "An email has been sent to you with those URLs" msgstr "Un mail vous a été envoyé avec toutes les URLs" -#: cfp/templates/cfp/propose.html:11 cfp/templates/cfp/speaker.html:11 -#: proposals/templates/proposals/participate.html:9 -msgid "Participate" -msgstr "Participer" - #: cfp/templates/cfp/propose.html:22 cfp/templates/cfp/speaker.html:21 +#: cfp/templates/cfp/staff/conference.html:13 msgid "Save" msgstr "Envoyer" +#: cfp/templates/cfp/staff/base.html:19 +#: cfp/templates/cfp/staff/conference.html:8 +msgid "Conference" +msgstr "Conférence" + #: cfp/templates/cfp/staff/base.html:29 msgid "Please select a category." msgstr "Veuillez sélectionner une catégorie." -#: cfp/templates/cfp/staff/participant_details.html:13 +#: cfp/templates/cfp/staff/participant_details.html:18 msgid "Informations" msgstr "Informations" -#: cfp/templates/cfp/staff/participant_details.html:15 +#: cfp/templates/cfp/staff/participant_details.html:20 msgid "E-mail:" msgstr "E-mail :" -#: cfp/templates/cfp/staff/participant_details.html:16 +#: cfp/templates/cfp/staff/participant_details.html:21 msgid "Twitter:" msgstr "Twitter :" -#: cfp/templates/cfp/staff/participant_details.html:17 +#: cfp/templates/cfp/staff/participant_details.html:22 msgid "LinkedIn:" msgstr "LinkedIn :" -#: cfp/templates/cfp/staff/participant_details.html:18 +#: cfp/templates/cfp/staff/participant_details.html:23 msgid "Github:" msgstr "Github :" -#: cfp/templates/cfp/staff/participant_details.html:19 +#: cfp/templates/cfp/staff/participant_details.html:24 msgid "Website:" msgstr "Website :" -#: cfp/templates/cfp/staff/participant_details.html:20 +#: cfp/templates/cfp/staff/participant_details.html:25 msgid "Facebook:" msgstr "Facebook :" -#: cfp/templates/cfp/staff/participant_details.html:21 +#: cfp/templates/cfp/staff/participant_details.html:26 msgid "Mastodon:" msgstr "Mastodon :" -#: cfp/templates/cfp/staff/participant_details.html:22 +#: cfp/templates/cfp/staff/participant_details.html:27 msgid "Phone number:" msgstr "Numéro de téléphone :" -#: cfp/templates/cfp/staff/participant_details.html:23 +#: cfp/templates/cfp/staff/participant_details.html:28 msgid "Language:" msgstr "Langue :" -#: cfp/templates/cfp/staff/participant_details.html:39 +#: cfp/templates/cfp/staff/participant_details.html:38 #: proposals/templates/proposals/_talk_list.html:8 msgid "by" msgstr "par" -#: cfp/templates/cfp/staff/participant_details.html:42 +#: cfp/templates/cfp/staff/participant_details.html:41 #: cfp/templates/cfp/staff/talk_list.html:35 #: proposals/templates/proposals/_talk_list.html:11 #: proposals/templates/proposals/_talk_list.html:17 @@ -477,12 +509,12 @@ msgstr "par" msgid "and" msgstr "et" -#: cfp/templates/cfp/staff/participant_details.html:45 +#: cfp/templates/cfp/staff/participant_details.html:44 #: proposals/templates/proposals/_talk_list.html:14 msgid "in" msgstr "dans la session" -#: cfp/templates/cfp/staff/participant_details.html:51 +#: cfp/templates/cfp/staff/participant_details.html:50 #: proposals/templates/proposals/_talk_list.html:23 msgid "No talks" msgstr "Aucun exposé" @@ -526,6 +558,41 @@ msgid_plural "refused: %(refused)s" msgstr[0] "refusé : %(refused)s" msgstr[1] "refusés : %(refused)s" +#: cfp/templates/cfp/staff/talk_decide.html:8 +#: proposals/templates/proposals/talk_decide.html:9 +msgid "Are you sure to accept this proposals?" +msgstr "Êtes-vous sûr d’accepter cette propositon d’intervention ?" + +#: cfp/templates/cfp/staff/talk_decide.html:8 +#: proposals/templates/proposals/talk_decide.html:9 +msgid "Are you sure to decline this proposals?" +msgstr "Êtes-vous sûr de décliner cette propositon d’intervention ?" + +#: cfp/templates/cfp/staff/talk_decide.html:10 +#: proposals/templates/proposals/talk_decide.html:11 +msgid "Information about the proposals" +msgstr "Information sur la propositon d’intervention" + +#: cfp/templates/cfp/staff/talk_decide.html:11 +#: proposals/templates/proposals/talk_decide.html:12 +msgid "Title:" +msgstr "Titre :" + +#: cfp/templates/cfp/staff/talk_decide.html:12 +#: proposals/templates/proposals/talk_decide.html:13 +msgid "Kind:" +msgstr "Type d’intervention :" + +#: cfp/templates/cfp/staff/talk_decide.html:26 +#: proposals/templates/proposals/talk_decide.html:22 +msgid "Accept the proposal" +msgstr "Accepter la proposition" + +#: cfp/templates/cfp/staff/talk_decide.html:26 +#: proposals/templates/proposals/talk_decide.html:22 +msgid "Decline the proposal" +msgstr "Décliner la proposition" + #: cfp/templates/cfp/staff/talk_details.html:16 #: proposals/templates/proposals/talk_detail.html:19 msgid "No abstract provided." @@ -551,6 +618,33 @@ msgstr "Pas encore assignée." msgid "No notes." msgstr "Aucune note." +#: cfp/templates/cfp/staff/talk_details.html:96 +#: proposals/templates/proposals/talk_detail.html:108 +msgid "Moderation" +msgstr "Modération" + +#: cfp/templates/cfp/staff/talk_details.html:98 +#: cfp/templates/cfp/staff/talk_list.html:20 +#: proposals/templates/proposals/talk_detail.html:110 +#: proposals/templates/proposals/talk_list.html:52 +msgid "Status" +msgstr "Statut" + +#: cfp/templates/cfp/staff/talk_details.html:103 +#: proposals/templates/proposals/talk_detail.html:115 +msgid "Vote" +msgstr "Vote" + +#: cfp/templates/cfp/staff/talk_details.html:112 +#: proposals/templates/proposals/talk_detail.html:124 +msgid "vote" +msgstr "vote" + +#: cfp/templates/cfp/staff/talk_details.html:112 +#: proposals/templates/proposals/talk_detail.html:124 +msgid "average:" +msgstr "moyenne :" + #: cfp/templates/cfp/staff/talk_list.html:11 #: planning/templates/planning/room_list.html:28 #: proposals/templates/proposals/talk_list.html:43 @@ -569,12 +663,6 @@ msgstr "Titre" msgid "Intervention kind" msgstr "Type d’intervention" -#: cfp/templates/cfp/staff/talk_list.html:20 -#: proposals/templates/proposals/talk_detail.html:110 -#: proposals/templates/proposals/talk_list.html:52 -msgid "Status" -msgstr "Statut" - #: cfp/templates/cfp/staff/talk_list.html:42 #: proposals/templates/proposals/talk_list.html:78 msgid "Accepted" @@ -591,11 +679,11 @@ msgstr "Décliné" msgid "Pending, score: %(score)s" msgstr "En cours, score : %(score)s" -#: cfp/views.py:53 +#: cfp/views.py:62 msgid "Your talk \"{}\" has been submitted for {}" msgstr "Votre proposition \"{}\" a été transmise à {}" -#: cfp/views.py:54 +#: cfp/views.py:63 msgid "" "Hi {},\n" "\n" @@ -635,6 +723,24 @@ msgstr "" "{}\n" "\n" +#: cfp/views.py:154 proposals/views.py:321 +msgid "Vote successfully created" +msgstr "A voté !" + +#: cfp/views.py:154 proposals/views.py:321 +msgid "Vote successfully updated" +msgstr "Vote mis à jour" + +#: cfp/views.py:177 proposals/views.py:347 +msgid "Decision taken in account" +msgstr "Décision enregistrée" + +#: cfp/views.py:207 +#, fuzzy +#| msgid "Vote successfully created" +msgid "Modifications successfully saved." +msgstr "A voté !" + #: conversations/templates/conversations/_message_form.html:4 msgid "Send a message" msgstr "Envoyer un message" @@ -728,6 +834,10 @@ msgstr "Accueil" msgid "Call for participation" msgstr "Appel à participation" +#: ponyconf/templates/base.html:36 +msgid "Staff" +msgstr "" + #: ponyconf/templates/base.html:50 #: ponyconf/templates/registration/login.html:10 msgid "Login" @@ -950,26 +1060,6 @@ msgstr "Contacter :" msgid "link" msgstr "lien" -#: proposals/templates/proposals/talk_decide.html:9 -msgid "Are you sure to accept this proposals?" -msgstr "Êtes-vous sûr d’accepter cette propositon d’intervention ?" - -#: proposals/templates/proposals/talk_decide.html:9 -msgid "Are you sure to decline this proposals?" -msgstr "Êtes-vous sûr de décliner cette propositon d’intervention ?" - -#: proposals/templates/proposals/talk_decide.html:11 -msgid "Information about the proposals" -msgstr "Information sur la propositon d’intervention" - -#: proposals/templates/proposals/talk_decide.html:12 -msgid "Title:" -msgstr "Titre :" - -#: proposals/templates/proposals/talk_decide.html:13 -msgid "Kind:" -msgstr "Type d’intervention :" - #: proposals/templates/proposals/talk_decide.html:15 msgid "Information for the proposer" msgstr "Information à destination de l’auteur de la proposition" @@ -983,14 +1073,6 @@ msgstr "" "le ci-dessous. N’oubliez pas de spécifier à quelle proposition " "d’intervention votre message fait référence." -#: proposals/templates/proposals/talk_decide.html:22 -msgid "Accept the proposal" -msgstr "Accepter la proposition" - -#: proposals/templates/proposals/talk_decide.html:22 -msgid "Decline the proposal" -msgstr "Décliner la proposition" - #: proposals/templates/proposals/talk_detail.html:24 msgid "Format" msgstr "Format" @@ -1030,22 +1112,6 @@ msgstr "Télécharger" msgid "Assign to" msgstr "Assigner à" -#: proposals/templates/proposals/talk_detail.html:108 -msgid "Moderation" -msgstr "Modération" - -#: proposals/templates/proposals/talk_detail.html:115 -msgid "Vote" -msgstr "Vote" - -#: proposals/templates/proposals/talk_detail.html:124 -msgid "vote" -msgstr "vote" - -#: proposals/templates/proposals/talk_detail.html:124 -msgid "average:" -msgstr "moyenne :" - #: proposals/templates/proposals/talk_detail.html:138 msgid "No attendees yet." msgstr "Il n’y a pas encore d’inscrit." @@ -1151,18 +1217,6 @@ msgstr "Exposé proposé avec succès !" msgid "Talk assigned to track successfully!" msgstr "Exposé assigné à la session avec succès !" -#: proposals/views.py:321 -msgid "Vote successfully created" -msgstr "A voté !" - -#: proposals/views.py:321 -msgid "Vote successfully updated" -msgstr "Vote mis à jour" - -#: proposals/views.py:347 -msgid "Decision taken in account" -msgstr "Décision enregistrée" - #: proposals/views.py:445 msgid "Unregistered :-(" msgstr "Vous avez été désinscrit :-(" @@ -1209,6 +1263,3 @@ msgstr "Bénévoles" #: volunteers/templates/volunteers/volunteer_list.html:25 msgid "volunteer" msgstr "bénévole" - -#~ msgid "Conference" -#~ msgstr "Conférence" diff --git a/ponyconf/settings.py b/ponyconf/settings.py index 3df5e05..9f546e3 100644 --- a/ponyconf/settings.py +++ b/ponyconf/settings.py @@ -49,7 +49,7 @@ INSTALLED_APPS = [ 'djangobower', 'bootstrap3', #'registration', - #'django_select2', + 'django_select2', #'avatar', 'crispy_forms', @@ -208,6 +208,7 @@ BOOTSTRAP3 = { SELECT2_JS = 'select2/dist/js/select2.min.js' SELECT2_CSS = 'select2/dist/css/select2.min.css' +SELECT2_I18N_PATH = 'select2/dist/js/i18n' #AUTHENTICATION_BACKENDS = ['yeouia.backends.YummyEmailOrUsernameInsensitiveAuth'] LOGOUT_REDIRECT_URL = 'home' @@ -221,9 +222,15 @@ INCLUDE_REGISTER_URL = True CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', - } + }, + 'select2': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + 'LOCATION': 'select2', + }, } +SELECT2_CACHE_BACKEND = 'select2' + SERVER_EMAIL = 'ponyconf@example.com' EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'localhost' diff --git a/requirements.txt b/requirements.txt index 7a35780..c26ab7c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,7 @@ django<1.12 django-autoslug django-bootstrap3 django-bower +django-crispy-forms django-select2 django-colorful