Source

djangofr / docs / topics / db / models.txt

Full commit
   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
.. _topics-db-models:

==================
Écrire ses modèles
==================

.. module:: django.db.models

Un modèle constitue la seule et unique source de données à propos de vos
données. Il définit les champs essentiels et les comportements des données que
vous stockez. En général, chaque modèle correspond à une seule table dans la
base de données.

Les bases :

    * Chaque modèle est une classe python qui surcharge la classe
      :class:`django.db.models.Model`.
    * Chaque attribut du modèle est un champ de base de données.
    * Grâce à cela, Django vous donne un accès à son API d'accès à la base de
      données ; voir :ref:`topics-db-queries`.

.. seealso::

    Le `dépôt officiel d'exemple de modèles`_ est un bon complément à ce
    document. (Dans les sources de Django, ces exemples se trouvent dans le
    répertoire ``tests/modeltests``.)

    .. _dépôt officiel d'exemple de modèles: http://www.djangoproject.com/documentation/models/

Exemple rapide
==============

Cet exemple de modèle définit un objet ``Person`` qui a deux attributs :
``first_name`` et ``last_name`` ::

    from django.db import models

    class Person(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=30)

``first_name`` et ``last_name`` sont des champs_ du modèle. Chaque champ
correspond à un attribut de la classe, et chaque attribut correspond à une
colonne de la table dans la base de données.

Le modèle ``Person`` correspondrait à cette table :

.. code-block:: sql

    CREATE TABLE myapp_person (
        "id" serial NOT NULL PRIMARY KEY,
        "first_name" varchar(30) NOT NULL,
        "last_name" varchar(30) NOT NULL
    );

Quelques détails techniques :

    * Le nom de la table, ``myapp_person``, est créé automatiquement en
      fonction des métadonnées mais on peut forcer manuellement le nom des
      tables. Voir :ref:`table-names` pour plus de détails.
      
    * Un champ ``id`` est ajouté automatiquement, mais ce comportement peut
      être outrepassé. Voir :ref:`automatic-primary-key-fields`.
            
    * Le code SQL ``CREATE TABLE`` de cet exemple est formatté en utilisant
      la syntaxe PostgreSQL, mais il faut noter que Django génère du SQL en
      fonction du backend qui vous avez choisi dans votre :ref:`fichier de
      configuration <topics-settings>`.

Utilisation des modèles
=======================

Une fois que vous avez défini vos modèles, vous devez dire à Django que vous
allez *utiliser* ces modèles. Faites-le en éditant le fichier de configuration
et en changeant le paramètre :setting:`INSTALLED_APPS` pour ajouter le nom du
module qui contient votre fichier ``models.py``.

Par exemple, si vous avez mis les modèles de votre application dans le module
``mysite.myapp.models`` (la structure d'une application est créée par le
script :djadmin:`manage.py startapp <startapp>`), :setting:`INSTALLED_APPS`
devrait contenir entre autres ::

    INSTALLED_APPS = (
        #...
        'mysite.myapp',
        #...
    )

Lorsque vous ajoutez des nouvelles applications dans
:setting:`INSTALLED_APPS`, assurez-vous d'exécuter la commande
:djadmin:`manage.py syncdb <syncdb>`.

Champs
======

La partie la plus importante d'un modèle -- et la seule partie obligatoire --
est la liste des champs de la base de données qu'il définit. Les champs sont
des attributs de classe.

Exemple ::

    class Musician(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        instrument = models.CharField(max_length=100)

    class Album(models.Model):
        artist = models.ForeignKey(Musician)
        name = models.CharField(max_length=100)
        release_date = models.DateField()
        num_stars = models.IntegerField()

Types de champs
---------------

Chaque champ de votre modèle doit être une instance de la classe
:class:`~django.db.models.Field` appropriée. Django se base sur les types de
classe des champs pour déterminer :

    * Le type de colonne dans la base de données (e.g. ``INTEGER``,
      ``VARCHAR``).

    * Le widget à utiliser dans l'interface d'administration de Django, si
      vous comptez l'utiliser (e.g. ``<input type="text">``, ``<select>``).

    * Les conditions minimales de validation, utilisées dans l'interace
      d'administration et dans les formulaires auto-générés.

Django est livré d'origine avec des douzaines de types de champ ; vous pouvez
trouver la liste complète dans la :ref:`référence des champs
<model-field-types>`. Vous pouvez aisément écrire vos propres champs si ceux
de Django ne conviennent pas ; voir :ref:`howto-custom-model-fields`.

Options des champs
------------------

Chaque champ prend un certain nombre d'arguments qui lui sont spécifiques
(documentés dans la :ref:`référence des champs <model-field-types>`). Par
exemple, :class:`~django.db.models.CharField` (et ses sous-classes) demande un
argument :attr:`~django.db.models.CharField.max_length` qui détermine la
taille du champ ``VARCHAR`` de la base utilisé pour stocker les données.

Un certain nombre d'arguments sont communs à tous les types de champs. Tous
sont optionnels. Ils sont documentés dans la :ref:`reference
<common-model-field-options>`, mais voici un résumé rapide des plus utilisés :

    :attr:`~Field.null`
        S'il est égal à ``True``, Django va stocker les valeurs vides en
        ``NULL`` dans la base de données.
        Par défaut : ``False``.

    :attr:`~Field.blank`
        S'il est égal à ``True``, le champ peut être vide. Par défaut :
        ``False``.

        Notez que c'est différent de :attr:`~Field.null`.
        :attr:`~Field.null` est uniquement lié à la base de données, tandis
        que :attr:`~Field.blank` est lié à la validation des données. Si un
        champ a :attr:`blank=True <Field.blank>`, l'interface d'administration
        de Django autorisera les valeurs vides. Si un champ a
        :attr:`blank=False <Field.blank>`, le champ ne pourra pas être vide.

    :attr:`~Field.choices`
        Un itérable (par exemple une liste ou un tuple) de deux tuples à
        utiliser comme choix pour ce champ. Si cet argument est fourni,
        l'interface d'administration de Django utilisera une liste déroulante
        plutôt que le champ de texte classique, et les choix possibles seront
        limités à ceux qui sont définis.

        Une liste de choix ressemble à ça ::

            YEAR_IN_SCHOOL_CHOICES = (
                ('FR', 'Freshman'),
                ('SO', 'Sophomore'),
                ('JR', 'Junior'),
                ('SR', 'Senior'),
                ('GR', 'Graduate'),
            )

    :attr:`~Field.default`
        La valeur par défaut de ce champ. Cela peut être une valeur ou un
        objet appelable. Si c'est un objet, il sera appelé à chaque fois qu'un
        nouvel objet est créé.

    :attr:`~Field.help_text`
        Texte d'aide à afficher sous le champ dans le formulaire de l'objet.
        C'est utile pour documenter même si votre objet n'est pas
        administrable.

    :attr:`~Field.primary_key`
        S'il est égal à ``True``, ce champ est la clé primaire pour le modèle.

        Si vous ne spécifiez pas :attr:`primary_key=True <Field.primary_key>`
        dans aucun champ de votre modèle, Django ajoutera automatiquement un
        :class:`IntegerField` qui constituera la clé primaire, et vous n'avez
        donc pas forcément à mettre :attr:`primary_key=True
        <Field.primary_key>` pour quelque champ que ce soit, à moins de
        vouloir passer outre le comportement par défaut. Pour plus
        d'informations, voir :ref:`automatic-primary-key-fields`.

    :attr:`~Field.unique`
        S'il est égal à ``True``, ce champ devra être unique dans la table.

Encore une fois, ce ne sont que des courtes descriptions des champs les plus
courants. La documentation comple peut être consultée dans la :ref:`référence
des champs de modèles <common-model-field-options>`.

.. _automatic-primary-key-fields:

Champs de clé primaire auto-incrémentés
---------------------------------------

Par défaut, Django ajoute le champ suivant à chaque modèle ::

    id = models.AutoField(primary_key=True)

Il s'agit d'une clé primaire auto-incrémentée.

Si vous avez besoin d'une clé primaire personnalisée, renseignez simplement
l'argument :attr:`primary_key=True <Field.primary_key>` dans un de vos champs.
Si Django voit que vous avez déterminé explicitement une
:attr:`Field.primary_key`, il n'ajoutera pas la colonne ``id``.

Chaque modèle doit avoir un et un seul champ ayant l'argument
:attr:`primary_key=True <Field.primary_key>`.

Noms complets
-------------

Chaque type de champ, mis à part :class:`~django.db.models.ForeignKey`,
:class:`~django.db.models.ManyToManyField` et
:class:`~django.db.models.OneToOneField`, prend un argument facultatif en
première position -- un nom complet. Si le nom complet n'est pas renseigné,
Django va automatiquement en créer un en utilisant le nom de l'attribut et en
convertissant les underscores en espaces.

Dans cet exemple, le nom complet est ``"Person's first name"`` ::

    first_name = models.CharField("Person's first name", max_length=30)

Dans cet exemple, le nom complet est ``"first name"`` ::

    first_name = models.CharField(max_length=30)

Pour :class:`~django.db.models.ForeignKey`,
:class:`~django.db.models.ManyToManyField` et
:class:`~django.db.models.OneToOneField`, le premier argument doit être une
classe de modèle, il faut donc utiliser l'argument :attr:`~Field.verbose_name`
::

    poll = models.ForeignKey(Poll, verbose_name="the related poll")
    sites = models.ManyToManyField(Site, verbose_name="list of sites")
    place = models.OneToOneField(Place, verbose_name="related place")

Par convention, on ne met pas de majuscule à la première lettre d'un
:attr:`~Field.verbose_name`. Django transforme automatiquement la première
lettre en majuscule lorsqu'il en a besoin.

Associations
------------

De toute évidence, la puissance des bases de données relationelles réside dans
les associations entre les tables. Django offre plusieurs moyens pour définir
les trois types d'association les plus courants : plusieurs-un ("many-to-one),
plusieurs-plusieurs (many-to-many), un-un (one-to-one).

Associations "many-to-one"
~~~~~~~~~~~~~~~~~~~~~~~~~~

Pour définir une association ""many-to-one", utilisez le champ
:class:`~django.db.models.ForeignKey`. Il s'utilise comme un autre
:class:`~django.db.models.Field`, en le mettant en attribut de votre modèle.

Le champ :class:`~django.db.models.ForeignKey` a besoin d'un argument : la
classe de modèle à laquelle il est relié.

Par exemple, si un modèle ``Car`` a un ``Manufacturer`` -- ce qui veut dire
qu'un ``Manufacturer`` fabrique plusieurs voitures mais chaque ``Car`` n'a
qu'un ``Manufacturer`` -- utilisez la syntaxe suivante ::

    class Manufacturer(models.Model):
        # ...

    class Car(models.Model):
        manufacturer = models.ForeignKey(Manufacturer)
        # ...
        
Vous pouvez également créer des :ref:`associations récursives
<recursive-relationships>` (dans un objet avec une association many-to-one
vers lui-même) et des :ref:`associations avec des modèles non encore définis
<lazy-relationships>` ; voir la :ref:`référence des champs <ref-foreignkey>`
pour plus d'informations.

Il est suggéré mais non imposé que le nom d'un champ
:class:`~django.db.models.ForeignKey` (``manufacturer`` dans l'exemple
précédent) soit le nom du modèle, en minuscule. Vous pouvez évidemment appeler
le champ comme vous voulez, par exemple ::

    class Car(models.Model):
        company_that_makes_it = models.ForeignKey(Manufacturer)
        # ...

.. seealso::

    Voir l'`exemple d'association many-to-one`_ pour un exemple complet.

.. _exemple d'association many-to-one: http://www.djangoproject.com/documentation/models/many_to_one/

Les champs :class:`~django.db.models.ForeignKey` peuvent aussi prendre un
certain nombre d'arguments qui sont détaillés dans :ref:`la référence des
modèles<foreign-key-arguments>`. Ces options permettent de définir comment
l'association fonctionne, elles sont toutes facultatives.

Associations "many-to-many"
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Pour définir une association "many-to-many", utilisez le champ
:class:`~django.db.models.ManyToManyField`. Vous pouvez l'utiliser comme un
autre type de :class:`~django.db.models.Field`, en l'incluant en attribut dans
votre classe de modèle.

Le champ :class:`~django.db.models.ManyToManyField` requiert un argument en
première position : la classe à laquelle le modèle est lié.

Par exemple, si un modèle ``Pizza`` a plusieurs objets ``Topping`` -- ce qui
signifie qu'un objet ``Topping`` peut se trouver sur plusieurs pizzas et
chaque ``Pizza`` a plusieurs ingrédients -- voici comment on le représenterait
::

    class Topping(models.Model):
        # ...

    class Pizza(models.Model):
        # ...
        toppings = models.ManyToManyField(Topping)

Comme avec une :class:`~django.db.models.ForeignKey`, vous pouvez aussi créer
des :ref:`associations récursives <recursive-relationships>` (un objet avec une
association many-to-one avec lui-même) et des :ref:`associations vers des
modèles non encore définis <lazy-relationships>` ; voir :ref:`la référence des
modèles <ref-manytomany>` pour plus de détails.

Il est suggéré mais non imposé que le nom d'un champ
:class:`~django.db.models.ManyToManyField` (``toppings`` dans l'exemple
précédent) soit un nom pluriel décrivant l'ensemble des objets liés.

Il n'y a pas d'importance au sujet du modèle qui a l'attribut
:class:`~django.db.models.ManyToManyField`, mais vous n'en avez besoin que
dans un modèle, pas les deux.

En général, les instances de champs :class:`~django.db.models.ManyToManyField`
devraient être situées dans l'objet qui sera édité dans l'interface
d'administration, si vous l'utilisez. Dans l'exemple précédent, une ``Pizza``
contient des ``toppings`` (plutôt que des ``Topping`` ayant un champ
:class:`~django.db.models.ManyToManyField` ``pizzas``), parce qu'il est plus
naturel de penser aux ingrédients de la garniture d'une pizza plutôt qu'à un
ingrédient se trouvant sur un certain nombre de pizzas. Vu la manière dont
cela a été défini précédemment, le formulaire d'administration d'une ``Pizza``
permettra aux utilisateurs de sélectionner plusieurs ingrédients.

.. seealso:: 

    Voir aussi l'`exemple d'association many-to-many`_ pour un exemple complet.

.. _exemple d'association many-to-many: http://www.djangoproject.com/documentation/models/many_to_many/

Les champs :class:`~django.db.models.ManyToManyField` acceptent un certain
nombre d'arguments qui sont détaillés dans la :ref:`référence des modèles
<manytomany-arguments>`. Ces options aident à définit comment fonctionne
l'association. Elles sont toutes facultatives.

.. _intermediary-manytomany:

Champs supplémentaires dans les associations many-to-many
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 1.0

Lorsque vous n'avez affaire qu'à des associations many-to-many simples comme
mélanger et faire correspondre des pizzas et des ingrédients, vous n'avez
besoin de rien de plus qu'une classe
:class:`~django.db.models.ManyToManyField` toute simple. Cependant, de temps
en temps vous pouvez avoir besoin d'associer les données avec l'association
entre deux modèles.

Par exemple, prenons le cas d'une application qui gère les groupes de musique
auxquels les musiciens appartiennent. Il y a une association many-to-many entre
une personne et les groupes dont elle fait partie, vous pourriez donc utiliser
un champ :class:`~django.db.models.ManyToManyField` pour représenter cette
association. Cependant, il y a beaucoup de détails au sujet de l'association
que vous aimeriez connaitre, comme par exemple la date à laquelle la personne
a rejoint le groupe.

Pour ce genre de situation, Django vous permet de spécifier le modèle qui sera
utilisé pour définir l'association many-to-many. Vous pouvez ainsi ajouter des
champs supplémentaires au modèle intermédiaire. Le modèle intermédiaire est
associé avec le champ :class:`~django.db.models.ManyToManyField` grâce à
l'argument :attr:`through <ManyToManyFields.through>`, qui pointe vers le
modèle qui sert d'intermédiaire. Pour notre exemple musical, le code
ressemblerait à ceci ::

    class Person(models.Model):
        name = models.CharField(max_length=128)

        def __unicode__(self):
            return self.name

    class Group(models.Model):
        name = models.CharField(max_length=128)
        members = models.ManyToManyField(Person, through='Membership')

        def __unicode__(self):
            return self.name

    class Membership(models.Model):
        person = models.ForeignKey(Person)
        group = models.ForeignKey(Group)
        date_joined = models.DateField()
        invite_reason = models.CharField(max_length=64)

Lorsque vous définissez un modèle intermédiaire, vous spécifiez explicitement
les clés étrangères vers les modèles qui sont impliqués dans l'association
many-to-many. Cette déclaration explicite définit donc comment deux modèles
sont associés.

Le modèle intermédiaire a quelques restrictions :

    * Votre modèle intermédiaire ne doit contenir qu'une et *une seule* clé
      étrangère vers le modèle cible (ce serait un objet ``Person`` dans notre
      exemple). Si vous avez plus d'une clé étrangère, une erreur de
      validation sera levée.
  
    * Votre modèle intermédiaire ne doit contenir qu'une et *une seule* clé
      étrangère vers le modèle source (``Group`` dans notre exemple). Si vous
      avez plus d'une clé étrangère, une erreur de validation sera levée.

    * La seule exception à cette règle est dans le cas où un modèle a une
      association many-to-many avec lui-même, à travers un modèle
      intermédiaire. Dans ce cas, deux clés étrangères sont autorisées, mais
      elles seront considérées comme les deux parties (différentes) de
      l'association many-to-many.
    
    * Lorsque vous définissez une association many-to-many entre un modèle et
      lui-même, en utilisant un modèle intermédiaire, vous *devez* utiliser
      l'argument :attr:`symmetrical=False <ManyToManyFields.symmetrical>`
      (voir la :ref:`référence des modèles <manytomany-arguments>`).

Maintenant que vous avez défini votre champ
:class:`~django.db.models.ManyToManyField` pour utiliser un modèle
intermédiaire, (``Membership`` dans ce cas), vous êtes prêt à définir quelques
associations many-to-many. Vous le faites en créant des instances du modèle
intermédiaire ::
    
    >>> ringo = Person.objects.create(name="Ringo Starr")
    >>> paul = Person.objects.create(name="Paul McCartney")
    >>> beatles = Group.objects.create(name="The Beatles")
    >>> m1 = Membership(person=ringo, group=beatles,
    ...     date_joined=date(1962, 8, 16), 
    ...     invite_reason= "Needed a new drummer.")
    >>> m1.save()
    >>> beatles.members.all()
    [<Person: Ringo Starr>]
    >>> ringo.group_set.all()
    [<Group: The Beatles>]
    >>> m2 = Membership.objects.create(person=paul, group=beatles,
    ...     date_joined=date(1960, 8, 1), 
    ...     invite_reason= "Wanted to form a band.")
    >>> beatles.members.all()
    [<Person: Ringo Starr>, <Person: Paul McCartney>]

Contrairement aux champs many-to-many classiques, vous ne *pouvez pas*
utiliser ``add``, ``create`` ou faire des assignations (par exemple
``beatles.members = [...]``) pour créer des associations ::

    # ÇA NE FONCTIONNERA PAS
    >>> beatles.members.add(john)
    # ÇA NON PLUS
    >>> beatles.members.create(name="George Harrison")
    # ET ÇA NON PLUS
    >>> beatles.members = [john, paul, ringo, george]

Pourquoi ? Vous ne pouvez pas juste créer des association entre une ``Person``
et un ``Group`` -- vous devez préciser tous les renseignements demandés par le
modèle ``Membership``. Les appels à ``add``, ``create`` ou à des assignations
ne permettent pas de fournir les détails supplémentaires. Par conséquent, ils
sont désactivés pour les associations many-to-many qui utilisent un modèle
intermédiaire. La seule façon de créer ce type d'association est d'instancier
le modèle intermédiaire.

La méthode ``remove`` est désactivée pour des raisons similaires. Cependant la
méhode ``clear()`` peut être utilisée pour supprimer toutes les associations
many-to-many d'une instance ::

    # Les Beatles se sont séparés
    >>> beatles.members.clear()

Une fois que vous avez mis en place vos associations many-to-many en créant
des instances du modèle intemédiaire, vous pouvez lancer des requêtes. Tout
comme avec les associations many-to-many classiques, vous pouvez lancer des
requêtes en utilisant les attributs du modèle lié ::

    # Trouver tous les groupes ayant un membre dont le nom commence par 'Paul'
    >>> Groups.objects.filter(members__name__startswith='Paul')
    [<Group: The Beatles>]

Comme vous utilisez un modèle intermédiaire, vous pouvez aussi lancer des
requêtes sur les attributs ::

    # Trouver tous les membres des Beatles qui ont rejoint le groupe après le
    # 1er Janvier 1961
    >>> Person.objects.filter(
    ...     group__name='The Beatles',
    ...     membership__date_joined__gt=date(1961,1,1))
    [<Person: Ringo Starr]
    

Associations one-to-one
~~~~~~~~~~~~~~~~~~~~

Pour définir une association one-to-one, on utilise le champ
:class:`~django.db.models.OneToOneField`. Il s'utilise comme tout autre type
de ``Field`` : en l'ajoutant en attribut de votre classe de modèle.

C'est très utile en tant que clé primaire d'un objet lorsque celui-ci "étend"
un autre objet d'une certaine manière.

Le champ :class:`~django.db.models.OneToOneField` requiert un argument en
première position : la classe à laquelle le modèle est associé.

Par exemple, si vous étiez en train d'établir une base de données
d'"endroits", vous auriez écrit des choses relativement classiques comme une
adresse, un numéro de téléphone, etc. dans la base de données. Puis, si vous
voulez construire une base de données de restaurants basée sur ces endroits,
plutôt que de vous répéter et copier ces champs dans le modèle ``Restaurant``,
vous pouvez associer un ``Restaurant`` avec un ``Endroit`` grâce à un champ
:class:`~django.db.models.OneToOneField` (puisqu'un restaurant "est" un
endroit ; en fait, pour faire cela vous auriez typiquement utilisé
:ref:`l'héritage  <model-inheritance>`, qui fait intervenir une association
one-to-one implicite).

Tout comme une :class:`~django.db.models.ForeignKey`, une :ref:`association
récursive <recursive-relationships>` peut être définie et il est possible de
:ref:`référencer des modèles encore non définis <lazy-relationships>` ; voir
la :ref:`référence des modèles <ref-onetoone>` pour plus de détails.

.. seealso::

    Voir l'`exemple d'association one-to-one`_ pour un exemple détaillé.

.. _exemple d'association one-to-one: http://www.djangoproject.com/documentation/models/one_to_one/

.. versionadded:: 1.0

Le champ :class:`~django.db.models.OneToOneField` accepte aussi un argument
optionnel décrit dans la :ref:`référence des modèles <ref-onetoone>`.

Par le passé, les classe :class:`~django.db.models.OneToOneField` étaient
automatiquement les clés primaire du modèle. Cela n'est plus le cas (bien que
vous pouvez toujours utiliser l'argument
:attr:`~django.db.models.Field.primary_key` si vous voulez). De fait, il est
maintenant possible d'avoir plusieurs champs de type
:class:`~django.db.models.OneToOneField` dans un modèle.

Modèles et fichiers
-------------------

Il n'y a pas de problème à relier un modèle à un autre d'une autre
application. Il vous suffit d'importer le modèle associé dans votre modèle.
Puis faites références à la classe de modèle lorsque vous en avez besoin. par
exemple ::

    from mysite.geography.models import ZipCode

    class Restaurant(models.Model):
        # ...
        zip_code = models.ForeignKey(ZipCode)

Restrictions de noms de champs
------------------------------

Django ne vous impose que deux restrictions pour le nom d'un champ :

    1. Un champ ne doit pas être une instruction Python, puisque cela
       provoquerait une erreur de syntaxe. Par exemple ::

           class Example(models.Model):
               pass = models.IntegerField() # 'pass' est un mot réservé !

    2. Un champ ne peut pas contenir plus d'un undersocre à la suite, du fait
       de la manière dont la syntaye des requêtes fonctionne. Par exemple ::

           class Example(models.Model):
               foo__bar = models.IntegerField() # 'foo__bar' a deux underscores !

Cependant, ces limitations peuvent être contournées, puisque vos noms de champ
ne correspondent pas nécessairement aux noms de colonne dans la base de
données. Voir l'option :attr:`~Field.db_column`.

Les instructions SQL telles que ``join``, ``where`` ou ``select`` *sont*
autorisées comme noms de champs, puisque Django échappe tous les noms de
tables et de colonnes dans toutes les requêtes SQL. Il utilise la syntaxe
d'échappement de votre base de données.

Types de champs personnalisés
-----------------------------

.. versionadded:: 1.0

Si l'un des champs existant ne peut pas être utilisé pour répondre à vos
besoins, ou si vous voulez profiter d'un type de colonne peu commun, vous
pouvez créer votre propre classe de champ. Une documentation complète sur
l'écriture de champs personnalisés se trouve dans
:ref:`howto-custom-model-fields`.

.. _meta-options:

Options Méta
============

Ajoutez des métadonnées à votre modèle en utilisant une ``class Meta``, come
cela ::

    class Ox(models.Model):
        horn_length = models.IntegerField()

        class Meta:
            ordering = ["horn_length"]
            verbose_name_plural = "oxen"

Les métadonnés sont "tout ce qui n'est pas un champ", comme des options de
classement (:attr:`~Options.ordering`), le nom de la table dans la base de
données (:attr:`~Options.db_table`), ou les noms singuliers et pluriels
lisibles (:attr:`~Options.verbose_name` et
:attr:`~Options.verbose_name_plural`). Aucun n'est obligatoire, et l'ajout de
la ``class Meta`` à un modèle est complètement facultatif.

Une liste complète des options ``Meta`` se trouve dans la :ref:`référence des
options des modèles <ref-models-options>`.

.. _model-methods:

Méthodes de modèle
==================

Vous pouvez écrire des méthodes dans un modèle pour ajouter des
fonctionnalités à vos objets. Alors que les méthodes du
:class:`~django.db.models.Manager` sont conçues pour faire des opérations sur
la table, les méthodes de modèle influent sur une instance particulière.

C'est une excellente technique pour garder la logique métier à un seul endroit
-- le modèle.

Par exemple, ce modèle a quelques méthodes personnalisées ::

    from django.contrib.localflavor.us.models import USStateField

    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        birth_date = models.DateField()
        address = models.CharField(max_length=100)
        city = models.CharField(max_length=50)
        state = USStateField() # Américains seulement...

        def baby_boomer_status(self):
            "Statut de la personne par rapport au baby-boom."
            import datetime
            if datetime.date(1945, 8, 1) <= self.birth_date <= datetime.date(1964, 12, 31):
                return "Baby boomer"
            if self.birth_date < datetime.date(1945, 8, 1):
                return "Pre-boomer"
            return "Post-boomer"

        def is_midwestern(self):
            "Renvoie True si la personne est de l'ouest central."
            return self.state in ('IL', 'WI', 'MI', 'IN', 'OH', 'IA', 'MO')

        def _get_full_name(self):
            "Renvoie le nom complet de la personne."
            return '%s %s' % (self.first_name, self.last_name)
        full_name = property(_get_full_name)

La dernière métode de cet exemple est une :term:`property`. `Plus d'infos sur
les properties`_.

.. _Plus d'infos sur les properties: http://www.python.org/download/releases/2.2/descrintro/#property

La :ref:`référence des instances de modèles <ref-models-instances>` fournit
une liste complète des :ref:`méthodes fournies automatiquement à chaque modèle
<model-instance-methods>`. Vous pouvez en surcharger la plupart -- voir
ci-après, `surcharger les méthodes prédéfinies`_ -- mais il y a certaines
choses que vous définirez presque systématiquement :

    :meth:`~Model.__unicode__`
        Une "méthode magique" de python qui renvoie une "représentation"
        unicode de chaque objet. C'est ce qu'utiliseront Python et Django
        lorsqu'une instance a besoin d'être affichée sous forme d'une chaine
        de caractères. Cela se produit notamment lorsque vous affichez un
        objet dans une invite de commande ou dans l'interface
        d'administration.
        
        Cette méthode doit systématiquement être définie ; la méthode par
        défaut n'est pas très utile.
        
    :meth:`~Model.get_absolute_url`
        Cette méthode permet à Django de définir l'URL d'un objet. Django
        utilise ceci dans l'interface d'administration, à chaque fois qu'il
        faut déterminer l'URL d'un objet.
        
        Tous les objets qui ont une URL les identifiant de manière unique
        doivent avoir cette méthode.

Surcharger les méthodes prédéfinies
-----------------------------------

D'autres :ref:`méthdes des modèles <model-instance-methods>` encapsulent un
comportement vis-à-vis de la base de données. Vous aurez probablement envie de
personnaliser ce comportement. En particulier, il est classique de changer la
manière dont :meth:`~Model.save` et :meth:`~Model.delete` fonctionnent.

Vous êtes libres de surcharger ces méthodes (et n'importe quelle autre méthode
de modèle) pour changer leur comportement.

Un cas classique de surcharge des méthodes par défaut se rencontre lorsque
vous voulez que quelque chose se produise lorsqu'un objet est sauvegardé. Par
exemple (voir :meth:`~Model.save` pour la documentation sur les paramètres de
cette méthode) ::

    class Blog(models.Model):
        name = models.CharField(max_length=100)
        tagline = models.TextField()

        def save(self, force_insert=False, force_update=False):
            do_something()
            super(Blog, self).save(force_insert, force_update) # Appel de la "vraie" méthode save().
            do_something_else()

Vous pouvez aussi empêcher la sauvegarde ::

    class Blog(models.Model):
        name = models.CharField(max_length=100)
        tagline = models.TextField()

        def save(self, force_insert=False, force_update=False):
            if self.name == "Yoko Ono's blog":
                return # Yoko ne devrait jamais avoir son propre blog !
            else:
                super(Blog, self).save(force_insert, force_update) # Appel de la "vraie" méthode save().

Il est important de se souvenir d'appeler la méthode de la classe parente --
c'est cette histoire de ``super(Blog, self).save()`` -- pour vous assurer que
l'objet est toujours sauvegardé dans la base de données. Si vous n'appelez pas
la méthode parente, le comportement par défaut n'aura plus lieu et la base de
données ne sera pas altérée.

Exécution de requêtes SQL personnalisées
----------------------------------------

Une autre pratique courante est d'écrire des requêtes SQL personnalisées dans
les méthodes de modèles et les méthodes de modules. L'objet
:class:`django.db.connection <django.db.backends.DatabaseWrapper>` représente
la connection actuelle avec la base de données. Pour l'utiliser, appelez
:meth:`connection.cursor() <django.db.backends.DatabaseWrapper.cursor>` pour
récupérer un objet curseur. Puis appelez ``cursor.execute(sql, [params])``
pour exécuter l'instruction SQL et :meth:`cursor.fetchone()
<django.db.backends.CursorWrapper.fetchone>` ou :meth:`cursor.fetchall()
<django.db.backends.CursorWrapper.fetchall>` pour renvoyer les colonnes
contenant les résultats. Par exemple ::

    def my_custom_sql(self):
        from django.db import connection
        cursor = connection.cursor()
        cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
        row = cursor.fetchone()
        return row

:class:`connection <django.db.backends.DatabaseWrapper>` et :class:`cursor
<django.db.backends.CursorWrapper>` implémentent principalement l'API base de
données standard de Python -- voir :pep:`249` -- avec l'ajout de la
:ref:`gestion des transactions <topics-db-transactions>`. Si vous n'êtes pas
familier avec l'API de base de données de Python, notez que l'instruction SQL
dans :meth:`cursor.execute() <django.db.backends.CursorWrapper.execute>`
utilise des ``"%s"`` plutôt que d'ajouter directement les paramètres dans le
code SQL. Grâce à cette technique, la bibliothèque de base de données
sous-jacente échappera automatiquement le(s) paramètre(s) si cela s'avère
nécessaire. (Notez aussi que Django utilise ``"%s"`` et *non pas* ``"?"`` qui
est utilisé avec Python/SQLite, dans un but d'uniformité et de rectitude.)

Le mot de la fin : si vous ne voulez qu'ajouter une clause ``WHERE``
personnalisée, vous pouvez utiliser la méthode de requête
:meth:`~QuerySet.extra`, qui vous permet d'ajouter du code SQL dans une
requête.

.. _model-inheritance:

Héritage des modèles
====================

.. versionadded:: 1.0

L'héritage des modèles avec Django fonctionne presque comme l'héritage de
classes avec Python. La seule décision que vous devez prendre est de
déterminer si vous voulez que les modèles parents soient des modèles à part
entière (avec leurs propres tables), ou bien si les parents contiennent juste
les informations communes qui seront visibles uniquement via les modèles fils.

Souvent, vous voudrez que la classe parente contienne les informations que
vous ne voulez pas avoir à remplir pour chaque modèle fils. Cette classe ne
sera donc jamais utilisée de manière isolée, vous aurez besoin des
:ref:`classes abstraites <abstract-base-classes>`. Cependant, si vous surclassez un modèle
existant (un modèle d'une autre application), ou bien si vous voulez que
chaque modèle ait sa propre table dans la base de données, allez voir du côté
de :ref:`l'héritage multi-table <multi-table-inheritance>`

.. _abstract-base-classes:

Classes abstraites
------------------

Les classes abstraites sont utiles lorsque vous voulez stocker des
informations communes dans un certain nombre de modèles différents. Vous
écrivez votre classe de base et ajoutez ``abstract=True`` dans la classe
:ref:`Meta <meta-options>`. Ce modèle ne sera pas utilisé lors de la création
des tables, mais sera utilisé comme classe de base pour d'autres modèles. Ses
champs seront donc ajoutés à ceux de la classe fille. Vous ne devez pas
utiliser les mêmes noms dans la classe de base et dans la classe fille (Django
lèvera une exception).

Par exemple ::

    class CommonInfo(models.Model):
        name = models.CharField(max_length=100)
        age = models.PositiveIntegerField()

        class Meta:
            abstract = True

    class Student(CommonInfo):
        home_group = models.CharField(max_length=5)

Le modèle ``Student`` a trois champs : ``name``, ``age`` et ``home_group``. Le
modèle ``CommonInfo`` ne peut pas être utilisé comme un modèle Django
classique, puisque c'est une classe abstraite. Il ne génère pas de table, ne
dispose pas de manager et ne peut pas être instancié ou sauvegardé
directement.

Dans beaucoup de cas, cet héritage correspondra exactement à vos besoins. Il
permet de factoriser les informations communes au niveau du code Python, tout
en créant une table par modèle fils au niveau de la base de données.

Héritage ``Meta``
~~~~~~~~~~~~~~~~~

Lorsqu'une classe abstraite est déclarée, Django rend toutes les classes
:ref:`Meta <meta-options>` disponibles comme des attributs. Si une classe
fille ne déclare pas sa propre classe :ref:`Meta <meta-options>`, elle
héritera de la classe :ref:`Meta <meta-options>` de la classe parente. Si la
classe fille veut étendre la classe :ref:`Meta <meta-options>`, il suffit de
la surcharger. Par exemple ::

    class CommonInfo(models.Model):
        ...
        class Meta:
            abstract = True
            ordering = ['name']

    class Student(CommonInfo):
        ...
        class Meta(CommonInfo.Meta):
            db_table = 'student_info'

Django ajuste un paramètre de la classe :ref:`Meta <meta-options>` de la
classe abstraite : avant d'installer l'attribut :ref:`Meta <meta-options>`, il
réinitialise à ``abstract=False``. Cela signifie que les classes fille de la
classe abstraite deviennent automatiquement des classes non abstraites.
Évidemment, vous pouvez écrire une classe abstraite qui hérite d'une autre
classe abstraite. Il faut juste vous souvenir de réinitialiser
``abstract=True`` à chaque fois.

Certains attributs n'auraient pas de sens dans la classe :ref:`Meta
<meta-options>` d'une classe abstraite. par exemple, ajouter ``db_table``
voudrait dire que toutes les classes filles (ou du moins celles qui ne
définissent pas leur propre :ref:`Meta <meta-options>`) utiliseraient la même
table, ce qui est un comportement que vous ne désirez certainement pas.

.. _abstract-related-name:

Attention avec ``related_name``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Si vous utilisez l'attribut :attr:`~django.db.models.ForeignKey.related_name`
sur une ``ForeignKey`` ou un ``ManyToManyField``, vous devez systématiquement
spécifier un nom *unique* pour le champ. Cela aurait pour effet de poser
problème dans la classe abstraite, puisque les champs de cette classe se
retrouvent dans toutes les classes filles, avec exactement les mêmes valeurs
d'attributs (y compris :attr:`~django.db.models.ForeignKey.related_name`).

Pour éviter ce problème, lorsque vous utilisez
:attr:`~django.db.models.ForeignKey.related_name` dans une classe abstraite
(uniquement), une partie du nom doit être la chaine ``'%(class)s'``. Ceci est
remplacé par le nom de la classe fille (en minuscule) dans lequel le champ est
utilisé. Puisque chaque classe a un nom différent, chaque nom connexe sera
différent. Par exemple ::

    class Base(models.Model):
        m2m = models.ManyToMany(OtherModel, related_name="%(class)s_related")

        class Meta:
            abstract = True

    class ChildA(Base):
        pass

    class ChildB(Base):
        pass

Le nom du champ ``ChildA.m2m`` sera ``childa_related``, tandis que le nom du
champ ``ChildB.m2m`` sera ``childb_related``. À vous de voir comment utiliser
la portion ``'%(class)s'`` pour construire votre nom de classe, mais si vous
oubliez de l'utiliser, Django lèvera des erreurs lors de la validation de vos
modèles (ou quand vous exécutez :djadmin:`syncdb`).

Si vous ne donnez pas l'attribut
:attr:`~django.db.models.ForeignKey.related_name` pour un champ d'une classe
abstraite, le nom par défaut sera le nom de la classe fille suivi de
``'_set'``, comme ce serait le cas si vous aviez déclaré le champ directement
dans la classe fille. Par exemple, dans le code précédent, si l'attribut
:attr:`~django.db.models.ForeignKey.related_name` est oublié, le nom du champ
``m2m`` sera ``childa_set`` dans le cas de ``ChildA`` et ``childb_set`` dans
le cas de ``ChildB``.

.. _multi-table-inheritance:

Héritage multi-table
--------------------

Le second type d'héritage supporté par Django est lorsque chaque modèle dans
la hiérarchie est un modèle à part entière. Chaque modèle a sa propre table et
peut être appelé individuellement. La relation d'héritage introduit des liens
entre le modèle fils et chacun de ses parents (via un champ
:class:`~django.db.models.fields.OneToOneField` créé automatiquement). Par
exemple ::

    class Place(models.Model):
        name = models.CharField(max_length=50)
        address = models.CharField(max_length=80)

    class Restaurant(Place):
        serves_hot_dogs = models.BooleanField()
        serves_pizza = models.BooleanField()

Tous les champs de ``Place`` seront aussi disponibles dans ``Restaurant``,
bien que les données seront dans une autre table. Ces deux options sont
possibles ::

    >>> Place.objects.filter(name="Bob's Cafe")
    >>> Restaurant.objects.filter(name="Bob's Cafe")

Si vous avez un objet ``Place`` qui est aussi un ``Restaurant`` vous pouvez
passer de l'objet ``Place`` à l'objet ``Restaurant`` en utilisant le nom en
minuscule du modèle ::

    >>> p = Place.objects.filter(name="Bob's Cafe")
    # Si Bob's Cafe est un objet Restaurant, cela va donner la classe fille :
    >>> p.restaurant
    <Restaurant: ...>

Cependant, si ``p`` dans l'exemple précédent n'était *pas* un ``Restaurant``
(il a été créé directement en tant qu'objet ``Place`` ou était le parent d'une
autre classe), l'appel de ``p.restaurant`` aurait provoqué une erreur.

``Meta`` et héritage  multi-table
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Dans le cas de l'héritage multi-table, il est logique que la classe fille
hérite de la classe :ref:`Meta <meta-options>` de sa classe parente. Toutes
les options :ref:`Meta <meta-options>` ont déjà été appliquées à la classe
parente et les appliquer encore une fois amènerait à un comportement
contradictoire (contrairement au cas de la classe abstraite, où la classe
n'existe pas en tant que telle).

Ainsi, un modèle fils n'a pas accès à la classe :ref:`Meta <meta-options>` de
son objet parent. Cependant, on trouve quelques rares cas où le fils hérite du
comportement de parent : si le fils n'a pas d'attribut
:attr:`django.db.models.Options.ordering` ou
:attr:`django.db.models.Options.get_latest_by`, il va en hériter de son
parent.

Si le parent a une option de tri et vous ne voulez pas que le fils soit trié
d'une quelque manière que ce soit, vous pouvez désactiver le tri explicitement
::

    class ChildModel(ParentModel):
        ...
        class Meta:
            # Suppression du tri du parent
            ordering = []

Héritage et relations inverses
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Comme l'héritage multi-table utilise un champ
:class:`~django.db.models.fields.OneToOneField` implicite pour lier le fils et
le parent, il est possible de se déplacer du parent au fils, comme dans
l'exemple vu ci-dessus. Cependant, cette technique utilise la valeur de
:attr:`~django.db.models.ForeignKey.related_name` par défaut pour les
associations :class:`django.db.models.fields.ForeignKey` et
:class:`django.db.models.fields.ManyToManyField`. Si vous définissez ces types
d'association sur la sous-classe d'un autre modèle, vous **devez** spécifier
l'attribut :attr:`~django.db.models.ForeignKey.related_name` pour chacun de
ces champs. Si vous l'oubliez, Django vous le rappelera en renvoyant une
erreur lorsque vous lancez :djadmin:`validate` ou :djadmin:`syncdb`.

Par exemple, en utilisant encore la classe ``Place``, nous allons créer une
autre sous-classe avec un champ
:class:`~django.db.models.fields.ManyToManyField` ::

    class Supplier(Place):
        # Vous devez spécifier un related_name sur toutes les associations.
        customers = models.ManyToManyField(Restaurant, related_name='provider')


Spécifier le champ de lien parental
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Comme expliqué, Django crée automatiquement un champ
:class:`~django.db.models.fields.OneToOneField` liant votre classe fille à
n'importe quel modèle parent non abstrait. Si vous voulez controller le nom de
l'attribut liant au parent, vous pouvez créer cotre propre champ
:class:`~django.db.models.fields.OneToOneField` et lui donner l'attribut
:attr:`parent_link=True <django.db.models.fields.OneToOneField.parent_link>`
pour indiquer que votre champ est le lien vers la classe parente.

Héritage multiple
-----------------

Tout comme la surcharge en python, il est possible pour un modèle Django
d'hériter de plusieurs modèles parents. Souvenez-vous que les règles de Python
sont appliquées. La première classe dans laquelle apparait un nom particulier
(par exemple :ref:`Meta <meta-options>`) sera celle qui sera utilisée ; par
exemple, cela veut dire que si les multiples parents contiennent une classe
:ref:`Meta <meta-options>`, uniquement la première sera utilisée, et toutes
les autres seront ignorées.

En général, l'héritage de parents multiples n'est pas très utile. Le cas
d'utilisation principal où cela est utile est pour les classes "mix-in", pour
ajouter une méthode ou un champ particulier à chaque classe qui hérite du
mix-in. Essayez de maintenir votre hiérarchie d'héritage aussi simple que
possible pour ne pas avoir à vous démener pour déterminer d'où vient une
information donnée.