HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythondjangoMinor

Civil status database with Django

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
djangowithstatusdatabasecivil

Problem

I'm beginning with Django and I have a Civil Status project.
I created my first models.py in order to get a Form, but I had some advices in order to normalize my database.

I made this process and I would like to know what do you think about this new restructuration.

My old models.py :

```
from django.db import models
from django.forms import ModelForm
from .countries import CHOIX_PAYS # Importation de la liste des pays
from .sexe import CHOIX_SEXE # Importation de la liste des sexes

# Create my Form model BirthCertificate

class BirthCertificate(models.Model) :

nom = models.CharField('Nom', max_length=30, null=False) # Lastname
prenom = models.CharField('Prénom', max_length=30, null = False) # Firstname
sexe = models.CharField('Sexe', max_length=1, choices = CHOIX_SEXE) # Choice between 'M' or 'F'
birthday = models.DateField('Date de naissance', null=False)
birthhour = models.TimeField('heure de naissance', null=False)
birthcity = models.CharField('Ville de naissance', max_length = 30, null=False)
birthcountry = models.ForeignKey(Country)

nom_pere = models.CharField('Nom père', max_length=30, null=False)
prenom_pere = models.CharField('Prénom père', max_length=30, null=False)
birthday_pere = models.DateField('Date de naissance du père', null=False)
birthcity_pere = models.CharField('Ville de naissance du père', max_length=30, null=False)
birthcountry_pere = models.CharField('Pays de naissance du père', max_length=2, choices= CHOIX_PAYS)
job_pere = models.CharField('Profession du père', max_length=30, null=False)
adress_pere = models.CharField('Adresse du père', max_length=40, null=False)
ville_pere = models.CharField('Ville du père', max_length=30, null=False)
zip_pere = models.IntegerField('Code Postal du père', null=False)
pays_pere = models.CharField('Pays du père', max_length=2, choices= CHOIX_PAYS)

nom_mere = models.CharField('Nom mère', max_length=30, null=False)
prenom_m

Solution

Few things here:

  1. Parent1 and Parent2


It's not really clear why would you need to have parents in the separate tables while they both represent a person. There is no difference between parent1 and parent2 so they can be stored in the same table.

  1. Parent1/Parent2/BirthCertificate



They all share lots of common fields, so you can create an abstract class that will describe them all.

  1. Separate table for sex and title



I would not go for this, I don't see much of reasons to create a table with only 2 rows in it.

So, in the end, your code should look like this:

from django.db import models

SEX_CHOICES = (
    ('M', 'Male'),
    ('F', 'Female')
)

TITLE_CHOICES = (
    ('Mr', 'Mister'),
    ('Mrs', 'Missus')
)

class Country(models.Model):

    code = models.CharField(max_length=3, null=False)  # Example : 'FR' - 'US'
    pays = models.CharField(max_length=50, null=False)  # Example : 'France' - 'Etats-Unis'

    def __str__(self):
        return self.code

class Person(models.Model):

    class Meta:
        abstract = True

    lastname = models.CharField(max_length=30, null=False)
    firstname = models.CharField(max_length=30, null=False)
    sex = models.CharField(max_length=1, choices=SEX_CHOICES)
    birthday = models.DateField(null=False)
    birthhour = models.TimeField(null=False)
    birthcity = models.CharField(max_length=30, null=False)
    birthcountry = models.ForeignKey(Country)

    def __str__(self):
        return self.lastname

class Parent(Person):

    title = models.CharField(choices=TITLE_CHOICES)
    job = models.CharField(max_length=30, null=False)
    adress = models.CharField(max_length=30, null=False)
    city = models.CharField(max_length=30, null=False)
    zip = models.IntegerField(max_length=10, null=False)
    country = models.ForeignKey(Country)

class BirthCertificate(Person):

    parent1 = models.ForeignKey(Parent)
    parent2 = models.ForeignKey(Parent)

Code Snippets

from django.db import models

SEX_CHOICES = (
    ('M', 'Male'),
    ('F', 'Female')
)

TITLE_CHOICES = (
    ('Mr', 'Mister'),
    ('Mrs', 'Missus')
)


class Country(models.Model):

    code = models.CharField(max_length=3, null=False)  # Example : 'FR' - 'US'
    pays = models.CharField(max_length=50, null=False)  # Example : 'France' - 'Etats-Unis'

    def __str__(self):
        return self.code


class Person(models.Model):

    class Meta:
        abstract = True

    lastname = models.CharField(max_length=30, null=False)
    firstname = models.CharField(max_length=30, null=False)
    sex = models.CharField(max_length=1, choices=SEX_CHOICES)
    birthday = models.DateField(null=False)
    birthhour = models.TimeField(null=False)
    birthcity = models.CharField(max_length=30, null=False)
    birthcountry = models.ForeignKey(Country)

    def __str__(self):
        return self.lastname


class Parent(Person):

    title = models.CharField(choices=TITLE_CHOICES)
    job = models.CharField(max_length=30, null=False)
    adress = models.CharField(max_length=30, null=False)
    city = models.CharField(max_length=30, null=False)
    zip = models.IntegerField(max_length=10, null=False)
    country = models.ForeignKey(Country)


class BirthCertificate(Person):

    parent1 = models.ForeignKey(Parent)
    parent2 = models.ForeignKey(Parent)

Context

StackExchange Code Review Q#147775, answer score: 6

Revisions (0)

No revisions yet.