2
\$\begingroup\$

I'm really new with Django and I would like to get your minds, advices, ... in order to improve the first part of my project.

For the moment, I created a model form which is named Identity and users can fill the form, get a preview with modification before to submit data.

As I said, I'm beginning to use Django and I'm sure that my script need modification, maybe an easier way to do what I want.

My forms.py file :

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

from django import forms
from BirthCertificate.models import *

class IdentityForm(forms.ModelForm) :

    class Meta :
        model = Identity
        fields = '__all__'

My views.py file looks like :

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

from django.shortcuts import render, render_to_response
from django.http import HttpResponseRedirect, HttpResponse
from django.template import loader
from .models import Identity, Country
from .forms import IdentityForm


def IdentityAccueil(request) :

    template = loader.get_template('accueil_Identity.html') 
    return HttpResponse(template.render(request))

def IdentityFormulary(request) :

    form = IdentityForm(request.POST or None)
    template_name = 'form_Identity.html'

    if form.is_valid() :  
        if '_preview' in request.POST :
            post = form.save(commit=False)
            template_name = 'preview.html'

        elif '_save' in request.POST :
            post = form.save()
            return HttpResponseRedirect('formulaire_traite')

    context = {
        "form" : form,
            }
    return render(request, template_name, context)


def CompletedFormulary(request) :

    identity = Identity.objects.all().order_by("-id")[0]
    context = {
       "identity" : identity,
   }
    return render(request, 'recapitulatif_identity.html',context)


def Consultation(request) :

    identity = Identity.objects.all().order_by("-id")[:10] #Les 10 dernières fiches créées
    identity_France = Identity.objects.filter(country='64').order_by("-id")[:10] #Les 10 dernières fiches où la personne habite en France

    query = request.GET.get('q')
    if query :
        toto = Identity.objects.filter(lastname__icontains=query) 
    else :
        toto = []

    context = {
        "identity" : identity,
        "identity_France" : identity_France,
        "query" : query,
        "toto" : toto,
        }


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

My accueil_identity.html looks like :

<h2 align="center"> Gestion des fiches individuelles </align> </h2>

<p> Veuillez cliquer sur l'opération à effectuer : </p>
<p> </p>
<p>*    <a href="http://localhost:8000/Identity/formulaire">Créer une nouvelle fiche individuelle</a></p>
<p> *   <a href="http://localhost:8000/Identity/recherche">Consulter/Editer une fiche individuelle</a></p>
<p> *   Supprimer une fiche individuelle </p>

My form_identity.html file looks like :

<!--DOCTYPE html -->
<html>
<body>

<h1 align="center"> Formulaire de fiche individuelle </h1>

<form method='POST' action=''> {% csrf_token %}

<h3> Partie contenant les informations de la fiche individuelle </h3>
{{ form.as_ul }} 
{{ value|date:"%d/%m/%Y" }} 

<br></br>

<input type ="submit" name="_save" value="Valider la fiche individuelle" /> 
<input type ="submit" name="_preview" value="Prévisualiser la fiche individuelle" />

</form>

</body>
</html>

My preview.html file as following :

<h2 align="center"> Prévisualisation de la fiche individuelle </align> </h2>

<form method='POST' action='/Identity/accueil'> {% csrf_token %}
{% block content %} 

<h3> Récapitulatif des données enregistrées : </h3>

<li> Civilité : {{form.title}}</li>
<li> Nom : {{form.lastname}}</li>
<li> Prénom : {{form.firstname}}</li>
<li> Sexe : {{form.sex}}</li>
<li> Date de Naissance : {{form.birthday}}</li>
<li> Ville de Naissance : {{form.birthcity}}</li>
<li> Pays de Naissance : {{form.birthcountry}}</li>
<li> Nationalité : {{form.nationality}}</li>
<li> Profession : {{form.job}}</li>
<li> Adresse : {{form.adress}}</li>
<li> Ville : {{form.city}}</li>
<li> Code Postal : {{form.zip}}</li>
<li> Pays : {{form.country}}</li>
<li> Email : {{form.mail}}</li>
<li> Téléphone : {{form.phone}}</li>

{% endblock %} 

<br></br>

<input type ="submit" name="_save" value="Valider la fiche individuelle" />

</form>

And my recapitulative_identity.html file :

<h2 align="center"> Votre formulaire a été validé </align> </h2>

{% block content %} 

Votre personne porte le numéro : {{ identity.id }} 

<h3> Récapitulatif des données enregistrées : </h3>

<li> Civilité : {{identity.title}}</li>
<li> Nom : {{identity.lastname}}</li>
<li> Prénom : {{identity.firstname}}</li>
<li> Sexe : {{identity.sex}}</li>
<li> Date de Naissance : {{identity.birthday}}</li>
<li> Ville de Naissance : {{identity.birthcity}}</li>
<li> Pays de Naissance : {{identity.birthcountry}}</li>
<li> Nationalité : {{identity.nationality}}</li>
<li> Profession : {{identity.job}}</li>
<li> Adresse : {{identity.adress}}</li>
<li> Ville : {{identity.city}}</li>
<li> Code Postal : {{identity.zip}}</li>
<li> Pays : {{identity.country}}</li>
<li> Email : {{identity.mail}}</li>
<li> Téléphone : {{identity.phone}}</li>

<br></br>

{% endblock %} 

<br></br>

<form method='POST' action='/Identity/accueil'> {% csrf_token %}
<input type ="submit" value="Retour fiche identité" />
</form>

<form method='POST' action='/BirthCertificate/accueil'> {% csrf_token %}
<input type ="submit" value="Création d'un acte de naissance" />
</form>

My resume.html file :

<h2 align="center"> Affichage de toutes les fiches individuelles </align> </h2>

<br></br>

{% block content %}

<h4> Récapitulatif des 10 dernières fiches individuelles créées: </h4>
<ul>
{% for item in identity %}
   <li>{{ item }}</li>
{% endfor %}
</ul>

<h4> Récapitulatif des 10 dernières fiches individuelles créées habitant en France: </h4>
<ul>
{% for item in identity_France %}
   <li>{{ item }}</li>
{% endfor %}
</ul>

<h4> Recherche par nom </h4>

<form method="GET" action="">
    <input type="text"  name="q" placeholder="Rechercher un nom" value="{{ request.GET.q }}">
    <input type="submit" value="Rechercher">
 </form>

<ul>
{% for item in toto %}
   <li> {{ item }} </li>
{% endfor %}

</ul>

{% endblock %}

I need some advice, part of script in order to improve mine, ... :)

\$\endgroup\$
4
\$\begingroup\$

Naming

C’est vraiment bizarre to have some of the mots in French et d’autres in English.

I don't talk about the templates, where it is normal to use the language of the end user, but rather your views.py where you mix English and French at will.

You also use CamelCase for function names which is against PEP 8 recommendations. Your function names may be:

def identity_home(…

def identity_form(…

def identity_resume(…

def identity_listing(…

Simplifications

Since you already import render from django.shortcuts, you don't need loader:

def identity_home(request):
    return render(request, 'accueil_Identity.html')  # Keeping the template name but you may want to change it.

By the way, render_to_response is unused in your code and the documentation does not recommend to use it anyway; so you can safely drop it.

You can also use the shortcut redirect instead of an explicit HttpResponseRedirect, so you can feed it a view name and other arguments for the URL. More on that latter.

You also don't need to use the all() queryset if you are going to order_by(...) right after:

Identity.objects.all().order_by(..)

is equivalent to

Identity.objects.order_by(..)

Lastly, I would change toto = [] with

toto = Identity.objects.none()

just so toto always stores a queryset. Oh and change that variable name, this is not serious: queryset or search_result should do.

Lastly, country='64' does not mean anything. Especially given the fact that you import Country from your models. I don't know what it contains, but I’ll make a wild guess that country=Country.FRANCE will be better.

Race conditions

Getting the last entry in the database to retrieve the last form saved is error prone. It may work in your case where you’re the only one testing your system, but as soon as several user can work at the same time on this, it will be possible that, if two of same save a for roughtly at the same time, they will both see the summary of the last one. And this is an issue.

Instead, you should not rely on the order of actions, but on concrete informations. Here you can use the post you just created and use its id to uniquely identify it.

You will need to modify your URL patterns so that the URL named formulaire_traite take an id as its last parameter (adding something like /(?P<id>\d+) at the end of the URL should suffice) and use that id to retrieve the Identity to display.

All in all, your views.py may look like:

from django.shortcuts import render, redirect, get_object_or_404
from .models import Identity, Country
from .forms import IdentityForm


def identity_home(request):
    return render(request, 'accueil_Identity.html')


def identity_form(request):
    form = IdentityForm(request.POST or None)
    template_name = 'form_Identity.html'

    if form.is_valid() :  
        if '_save' in request.POST :
            post = form.save()
            return redirect('formulaire_traite', id=post.id)
        template_name = 'preview.html'

    return render(request, template_name, {"form" : form})


def identity_resume(request, id):
    identity = get_object_or_404(Identity, pk=id)
    context = {"identity": identity}
    return render(request, 'recapitulatif_identity.html', context)


def identity_listing(request):
    identitys = Identity.objects.order_by("-id")
    identity = identitys[:10]  # Les 10 dernières fiches créées
    identity_France = identity.filter(country='64')[:10]  # Les 10 dernières fiches où la personne habite en France

    query = request.GET.get('q')
    if query:
        search_results = Identity.objects.filter(lastname__icontains=query) 
    else:
        search_results = Identity.objects.none()

    context = {
        "identity": identity,
        "identity_France": identity_France,
        "query": query,
        "search": search_results,
    }

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

Templates

The <h3> and <li> tags are common to preview.html and recapitulative_identity.html. You can factorize that out. A base template like:

{% block pre_certificate %}{% endblock %}

<h3> Récapitulatif des données enregistrées : </h3>

<li> Civilité : {{certificate.title}}</li>
<li> Nom : {{certificate.lastname}}</li>
<li> Prénom : {{certificate.firstname}}</li>
<li> Sexe : {{certificate.sex}}</li>
<li> Date de Naissance : {{certificate.birthday}}</li>
<li> Ville de Naissance : {{certificate.birthcity}}</li>
<li> Pays de Naissance : {{certificate.birthcountry}}</li>
<li> Nationalité : {{certificate.nationality}}</li>
<li> Profession : {{certificate.job}}</li>
<li> Adresse : {{certificate.adress}}</li>
<li> Ville : {{certificate.city}}</li>
<li> Code Postal : {{certificate.zip}}</li>
<li> Pays : {{certificate.country}}</li>
<li> Email : {{certificate.mail}}</li>
<li> Téléphone : {{certificate.phone}}</li>

{% block post_certificate %}{% endblock %}

And use it to define preview.html:

{% block pre_certificate %}
<h2 align="center"> Prévisualisation de la fiche individuelle </align> </h2>

<form method='POST' action='/Identity/accueil'> {% csrf_token %}
{% endblock %} 

{% block post_certificate %}
<br></br>

<input type ="submit" name="_save" value="Valider la fiche individuelle" />

</form>
{% endblock %} 

and recapitulative_identity.html:

{% block pre_certificate %}
<h2 align="center"> Votre formulaire a été validé </align> </h2>

Votre personne porte le numéro : {{ certificate.id }} 
{% endblock %} 

{% block post_certificate %}
<br></br>

<form method='POST' action='/Identity/accueil'> {% csrf_token %}
<input type ="submit" value="Retour fiche identité" />
</form>

<form method='POST' action='/BirthCertificate/accueil'> {% csrf_token %}
<input type ="submit" value="Création d'un acte de naissance" />
</form>
{% endblock %} 

For that, you will need to change a bit the context used when rendering in identity_form and identity_resume to use 'certificate' instead of respectively 'form' and 'identity'.

\$\endgroup\$
  • \$\begingroup\$ Thank you very much ! Yes it's Frenglish because I'm showing my project to french people and I asked some things on StackOverflow? It's really ugly I know ! I really appreciated your answer ! I had not yet the Django Philosophy and it's a great pleasure to be corrected by people like you. I will take care your advices in order to improve my code :) \$\endgroup\$ – Essex Nov 29 '16 at 12:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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