2
\$\begingroup\$

I'm writting my Django website and I created a view function which let to filter data before filling my Django form.

It works pretty well but I would find a way to simplify this function. It seems really ugly and maybe it exists a way to do that.

My models.py file looks like this :

#-*- coding: utf-8 -*-

from django.db import models
from Identity.models import Person
from django.utils.encoding import force_text
from django_countries.fields import CountryField


STATUS_CHOICES = (
    ('Celibataire', 'Celibataire'),
    ('Divorce(e)', 'Divorce(e)'),
    ('Veuf/Veuve', 'Veuf/Veuve'),
)


class Acte_Mariage(models.Model):

    fk_epoux = models.ForeignKey(Person, related_name='Epoux', verbose_name='Epoux', null=False)
    fk_epouse = models.ForeignKey(Person, related_name='Epouse', verbose_name='Epouse', null=False)
    epoux_status = models.CharField(max_length=8, choices=STATUS_CHOICES, verbose_name="Statut matrimonial de l'époux")
    epouse_status = models.CharField(max_length=8, choices=STATUS_CHOICES, verbose_name="Statut matrimonial de l'épouse")

    fk_father_husband = models.ForeignKey(Person, related_name='Pere Epoux+', verbose_name='Pere Epoux', null=False)
    fk_mother_husband = models.ForeignKey(Person, related_name='Mere Epoux+', verbose_name='Mere Epoux', null=False)
    fk_father_wife = models.ForeignKey(Person, related_name='Pere Epouse+', verbose_name='Pere Epouse', null=False)
    fk_mother_wife = models.ForeignKey(Person, related_name='Mere Epouse+', verbose_name='Mere Epouse', null=False)

    fk_temoin1 = models.ForeignKey(Person, related_name='Temoin 1+', verbose_name='Temoin 1', null=False)
    fk_temoin2 = models.ForeignKey(Person, related_name='Temoin 2+', verbose_name='Temoin 2', null=False)
    fk_temoin3 = models.ForeignKey(Person, related_name='Temoin 3+', verbose_name='Temoin 3', null=False)
    fk_temoin4 = models.ForeignKey(Person, related_name='Temoin 4+', verbose_name='Temoin 4', null=False)

    created = models.DateTimeField(auto_now_add=True)

My forms.py file looks like :

#-*- coding: utf-8 -*-

from django import forms
from django.db.models import Q
from Mariage.models import *
from django_countries.widgets import CountrySelectWidget

class CustomLabelModelChoiceField(forms.ModelChoiceField):

    def __init__(self, *args, **kwargs):
        self._label_from_instance = kwargs.pop('label_func', force_text)
        super(CustomLabelModelChoiceField, self).__init__(*args, **kwargs)

    def label_from_instance(self, obj):
        return self._label_from_instance(obj)

class Acte_Mariage_Form(forms.ModelForm):
    fk_epoux = CustomLabelModelChoiceField(Person.objects.filter(sex = "Masculin"), required=False, label = "Epoux", label_func=lambda obj: '%s %s %s %s' % (obj.lastname, obj.firstname, obj.birthday, obj.birthcity))
    fk_epouse = CustomLabelModelChoiceField(Person.objects.filter(sex = "Feminin"), required=False, label = "Epouse", label_func=lambda obj: '%s %s %s %s' % (obj.lastname, obj.firstname, obj.birthday, obj.birthcity))

    fk_father_husband = CustomLabelModelChoiceField(Person.objects.filter(sex = "Masculin"), required=False, label = "Père Epoux", label_func=lambda obj: '%s %s %s %s' % (obj.lastname, obj.firstname, obj.birthday, obj.birthcity))
    fk_mother_husband = CustomLabelModelChoiceField(Person.objects.filter(sex = "Feminin"), required=False, label = "Mère Epoux", label_func=lambda obj: '%s %s %s %s' % (obj.lastname, obj.firstname, obj.birthday, obj.birthcity))

    fk_father_wife = CustomLabelModelChoiceField(Person.objects.filter(sex = "Masculin"), required=False, label = "Père Epouse", label_func=lambda obj: '%s %s %s %s' % (obj.lastname, obj.firstname, obj.birthday, obj.birthcity))
    fk_mother_wife = CustomLabelModelChoiceField(Person.objects.filter(sex = "Feminin"), required=False, label = "Mère Epouse", label_func=lambda obj: '%s %s %s %s' % (obj.lastname, obj.firstname, obj.birthday, obj.birthcity))

    fk_temoin1 = CustomLabelModelChoiceField(Person.objects.filter(Q(sex='Masculin') | Q(sex='Feminin')), required=False, label = "Témoin 1", label_func=lambda obj: '%s %s %s %s' % (obj.lastname, obj.firstname, obj.birthday, obj.birthcity))
    fk_temoin2 = CustomLabelModelChoiceField(Person.objects.filter(Q(sex='Masculin') | Q(sex='Feminin')), required=False, label = "Témoin 2", label_func=lambda obj: '%s %s %s %s' % (obj.lastname, obj.firstname, obj.birthday, obj.birthcity))
    fk_temoin3 = CustomLabelModelChoiceField(Person.objects.filter(Q(sex='Masculin') | Q(sex='Feminin')), required=False, label = "Témoin 3", label_func=lambda obj: '%s %s %s %s' % (obj.lastname, obj.firstname, obj.birthday, obj.birthcity))
    fk_temoin4 = CustomLabelModelChoiceField(Person.objects.filter(Q(sex='Masculin') | Q(sex='Feminin')), required=False, label = "Témoin 4", label_func=lambda obj: '%s %s %s %s' % (obj.lastname, obj.firstname, obj.birthday, obj.birthcity))


    class Meta :
        model = Acte_Mariage
        fields = ['fk_epoux', 'fk_epouse', 'epoux_status', 'epouse_status', 'fk_father_husband', 'fk_mother_husband', 'fk_father_wife', 'fk_mother_wife','fk_temoin1', 'fk_temoin2', 'fk_temoin3', 'fk_temoin4']
        widgets = {'country': CountrySelectWidget()}

    def __init__(self, *args, **kwargs):    
        super(Acte_Mariage_Form, self).__init__(*args, **kwargs)
        for key, value in self.fields.iteritems() :
            self.fields[key].widget.attrs.update({'class':'form-fields'})

And my views.py function :

@login_required
def Mariage_Form(request) :

    #Get lastname given by user
    query_lastname_husband = request.GET.get('lastname_husband')
    query_lastname_wife = request.GET.get('lastname_wife')

    query_lastname_father_husband = request.GET.get('lastname_father_husband')
    query_lastname_mother_husband = request.GET.get('lastname_mother_husband')

    query_lastname_father_wife = request.GET.get('lastname_father_wife')
    query_lastname_mother_wife = request.GET.get('lastname_mother_wife')

    query_lastname_temoin1 = request.GET.get('lastname_temoin1')
    query_lastname_temoin2 = request.GET.get('lastname_temoin2')
    query_lastname_temoin3 = request.GET.get('lastname_temoin3')
    query_lastname_temoin4 = request.GET.get('lastname_temoin4')

    if request.method == 'POST':

        if form.is_valid() :   # Vérification sur la validité des données
            post = form.save()
            return HttpResponseRedirect(reverse('M_treated', kwargs={'id': post.id}))

    else:
        form = Acte_Mariage_Form()

        husband = Person.objects.filter(lastname=query_lastname_husband)
        wife = Person.objects.filter(lastname=query_lastname_wife)

        father_husband = Person.objects.filter(lastname=query_lastname_father_husband)
        mother_husband = Person.objects.filter(lastname=query_lastname_mother_husband)

        father_wife = Person.objects.filter(lastname=query_lastname_father_wife)
        mother_wife = Person.objects.filter(lastname=query_lastname_mother_wife)

        temoin1 = Person.objects.filter(lastname=query_lastname_temoin1)
        temoin2 = Person.objects.filter(lastname=query_lastname_temoin2)
        temoin3 = Person.objects.filter(lastname=query_lastname_temoin3)
        temoin4 = Person.objects.filter(lastname=query_lastname_temoin4)

        form = Acte_Mariage_Form(request.POST or None)
        form.fields['fk_epoux'].queryset = husband.filter(sex="Masculin")
        form.fields['fk_epouse'].queryset = wife.filter(sex="Feminin")
        form.fields['fk_father_husband'].queryset = father_husband.filter(sex="Masculin")
        form.fields['fk_mother_husband'].queryset = mother_husband.filter(sex="Feminin")
        form.fields['fk_father_wife'].queryset = father_wife.filter(sex="Masculin")
        form.fields['fk_mother_wife'].queryset = mother_wife.filter(sex="Feminin")
        form.fields['fk_temoin1'].queryset = temoin1
        form.fields['fk_temoin2'].queryset = temoin2
        form.fields['fk_temoin3'].queryset = temoin3
        form.fields['fk_temoin4'].queryset = temoin4

    context = {
        "form" : form,
        "query_lastname_husband" : query_lastname_husband,
        "query_lastname_wife" : query_lastname_wife,
        "query_lastname_father_husband" : query_lastname_father_husband,
        "query_lastname_mother_husband" : query_lastname_mother_husband,
        "query_lastname_father_wife" : query_lastname_father_wife,
        "query_lastname_mother_wife" : query_lastname_mother_wife,
        "query_lastname_temoin1" : query_lastname_temoin1,
        "query_lastname_temoin2" : query_lastname_temoin2,
        "query_lastname_temoin3" : query_lastname_temoin3,
        "query_lastname_temoin4" : query_lastname_temoin4,
    }

    return render(request, 'M_form.html', context)

I know, it's a melting between English and French (I will modify this after). As you can see, my function is good but pretty heavy.

There is a way to simplify multiples requests ?

I get local variable 'form' referenced before assignment when I'm validating my form.

\$\endgroup\$

closed as off-topic by 409_Conflict, Graipher, alecxe, Toby Speight, Jamal May 17 '17 at 3:00

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions containing broken code or asking for advice about code not yet written are off-topic, as the code is not ready for review. After the question has been edited to contain working code, we will consider reopening it." – 409_Conflict, Graipher, alecxe, Toby Speight, Jamal
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    \$\begingroup\$ Besides the UnboundLocalError that make this question off-topic, French law does not require that the spouses are of different sex anymore. You may want to adapt your models as well. \$\endgroup\$ – 409_Conflict May 16 '17 at 14:01
  • \$\begingroup\$ Yes, you're right but they are 2 differences : This Civil State is not destined to French Administration and this law is very recent ;) But you're totally right ! \$\endgroup\$ – Essex May 16 '17 at 14:19
1
\$\begingroup\$

(I don't know neither Python nor French)

This code says you need to use a collection like dictionary:

query_lastname_husband = request.GET.get('lastname_husband')
query_lastname_wife = request.GET.get('lastname_wife')

query_lastname_father_husband = request.GET.get('lastname_father_husband')
query_lastname_mother_husband = request.GET.get('lastname_mother_husband')

query_lastname_father_wife = request.GET.get('lastname_father_wife')
query_lastname_mother_wife = request.GET.get('lastname_mother_wife')

query_lastname_temoin1 = request.GET.get('lastname_temoin1')
query_lastname_temoin2 = request.GET.get('lastname_temoin2')
query_lastname_temoin3 = request.GET.get('lastname_temoin3')
query_lastname_temoin4 = request.GET.get('lastname_temoin4')

Something like this:

last_name_dictionary = {'lastname_husband': '', 'lastname_wife': '', 'lastname_father_husband': '', 'lastname_mother_husband': ''}

# query the values
for key, value in last_name_dictionary.items():
  last_name_dictionary[key] = request.GET.get(key)

# now you have key-value pairs of the last names
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.