diff --git a/common/settings.py b/common/settings.py index 4fbc0a1..8d5514d 100644 --- a/common/settings.py +++ b/common/settings.py @@ -52,8 +52,9 @@ WSGI_APPLICATION = 'common.wsgi.application' DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': 'recettes', + 'USER': 'claude', } } diff --git a/recette/fields.py b/recette/fields.py new file mode 100644 index 0000000..2ba2b2a --- /dev/null +++ b/recette/fields.py @@ -0,0 +1,26 @@ +from django.contrib.postgres.fields import ArrayField +from django.forms import CheckboxSelectMultiple, TypedMultipleChoiceField + + +class ChoiceArrayField(ArrayField): + """ + From https://blogs.gnome.org/danni/2016/03/08/multiple-choice-using-djangos-postgres-arrayfield/ + A field that allows us to store an array of choices. + + Uses Django's postgres ArrayField and a MultipleChoiceField for its formfield. + See also https://code.djangoproject.com/ticket/27704 + """ + widget = CheckboxSelectMultiple + + def formfield(self, **kwargs): + defaults = { + 'form_class': TypedMultipleChoiceField, + 'coerce': self.base_field.to_python, + 'choices': self.base_field.choices, + 'widget': self.widget, + } + defaults.update(kwargs) + # Skip our parent's formfield implementation completely as we don't + # care for it. + # pylint:disable=bad-super-call + return super(ArrayField, self).formfield(**defaults) diff --git a/recette/forms.py b/recette/forms.py index 0126b75..e1b9d32 100644 --- a/recette/forms.py +++ b/recette/forms.py @@ -1,5 +1,19 @@ from django import forms +from .models import Recette + class SearchForm(forms.Form): text = forms.CharField(widget=forms.TextInput(attrs={'autofocus': True})) + saison = forms.ChoiceField(choices=(('all', "Toutes"),) + Recette.SAISON_CHOICES) + + def search(self): + if self.is_valid(): + qs = Recette.objects.all() + if self.cleaned_data['text']: + qs = qs.filter(nom__icontains=self.cleaned_data['text']) + if self.cleaned_data['saison'] != 'all': + qs = qs.filter(saison__contains=[self.cleaned_data['saison']]) + return qs + else: + return Recette.objects.none() diff --git a/recette/migrations/0002_recette_saison.py b/recette/migrations/0002_recette_saison.py new file mode 100644 index 0000000..fe9fc19 --- /dev/null +++ b/recette/migrations/0002_recette_saison.py @@ -0,0 +1,17 @@ +from django.db import migrations, models +from recette.fields import ChoiceArrayField + +class Migration(migrations.Migration): + + dependencies = [ + ('recette', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='recette', + name='saison', + field=ChoiceArrayField(base_field=models.CharField(blank=True, choices=[('printemps', 'Printemps'), ('été', 'Été'), ('automne', 'Automne'), ('hiver', 'Hiver')], max_length=10), default=[], size=None, verbose_name='Saison'), + preserve_default=False, + ), + ] diff --git a/recette/models.py b/recette/models.py index 697dc60..1b06524 100644 --- a/recette/models.py +++ b/recette/models.py @@ -1,6 +1,8 @@ from django.db import models from django.urls import reverse +from .fields import ChoiceArrayField + class Ingredient(models.Model): nom = models.CharField("Nom", max_length=200) @@ -17,9 +19,19 @@ class Unite(models.Model): class Recette(models.Model): + SAISON_CHOICES = ( + ('printemps', 'Printemps'), + ('été', 'Été'), + ('automne', 'Automne'), + ('hiver', 'Hiver'), + ) nom = models.CharField("Nom", max_length=200) photo = models.ImageField("Photo", upload_to='photos', blank=True) nb_pers = models.IntegerField(default=4) + saison = ChoiceArrayField( + models.CharField(max_length=10, choices=SAISON_CHOICES, blank=True), + verbose_name="Saison", + ) prep = models.TextField("Préparation", blank=True) source = models.CharField("Source", max_length=200, blank=True) ingredients = models.ManyToManyField(Ingredient, through='Composition', blank=True) diff --git a/recette/views.py b/recette/views.py index 38fe3b3..3093ce2 100644 --- a/recette/views.py +++ b/recette/views.py @@ -8,8 +8,7 @@ def home(request): form = SearchForm(request.POST or None) recettes = [] if request.method == 'POST': - if form.is_valid(): - recettes = Recette.objects.filter(nom__icontains=form.cleaned_data['text']) + recettes = form.search() return render(request, 'index.html', context={'form': form, 'recettes': recettes})