523 votes

Quelle est la différence entre django OneToOneField et ForeignKey ?

Quelle est la différence entre Django OneToOneField y ForeignKey ?

5voto

Rishab Mamgai Points 145

J'ai également été confus quant à l'utilisation de ces deux champs. Je vais vous donner un exemple pour comprendre leur utilisation, car j'ai été confronté à ce problème récemment et j'ai compris l'utilisation de ces deux champs.

J'avais un modèle, comme celui-ci

from django.contrib.auth.models import User
from django.db import models

class Attendance(models.Model):
     user = models.OneToOneField(User, on_delete=models.CASCADE, default="", null=True)
     date = models.CharField(max_length=11)

     def __int__(self):
         return self.id

Le problème, c'est que je ne peux pas créer plusieurs objets avec le même utilisateur, c'est-à-dire qu'un même utilisateur aura des présences sur plusieurs jours. D'où les objets multiples avec le même utilisateur.

Mais le champ OneToOne ne m'a pas permis de le faire. Image pour référence

Alors, j'ai changé mon modèle pour

from django.contrib.auth.models import User
from django.db import models

class Attendance(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, default="", null=True)
    date = models.CharField(max_length=11)

    def __int__(self):
        return self.id

Maintenant, cela fonctionne bien et je peux marquer la présence d'un utilisateur sur plusieurs jours.

C'est donc là que réside la différence : le champ OneToOne ne vous permettra pas de créer plusieurs objets avec le même utilisateur (à titre d'exemple), mais avec ForeignKey, c'est possible.

5voto

Nate Berman Points 194

Lorsque vous accédez à un champ OneToOneField, vous obtenez la valeur du champ que vous avez interrogé. Dans cet exemple, le champ "title" d'un modèle de livre est un OneToOneField :

>>> from mysite.books.models import Book
>>> b = Book.objects.get(id=50)
>>> b.title
u'The Django Book'

Lorsque vous accédez à un ForeignKey, vous obtenez l'objet de modèle associé, sur lequel vous pouvez ensuite effectuer d'autres requêtes. Dans cet exemple, le champ "publisher" du même modèle de livre est une clé étrangère (en corrélation avec la définition du modèle de classe Publisher) :

>>> b = Book.objects.get(id=50)
>>> b.publisher
<Publisher: Apress Publishing>
>>> b.publisher.website
u'http://www.apress.com/'

Avec les champs ForeignKey, les requêtes fonctionnent également dans l'autre sens, mais elles sont légèrement différentes en raison de la nature non symétrique de la relation.

>>> p = Publisher.objects.get(name='Apress Publishing')
>>> p.book_set.all()
[<Book: The Django Book>, <Book: Dive Into Python>, ...]

En coulisses, book_set est juste un QuerySet et peut être filtré et découpé comme n'importe quel autre QuerySet. Le nom de l'attribut book_set est généré en ajoutant le nom du modèle en minuscules à _set.

2voto

aarif faridi Points 27

OneToOneField : si la deuxième table est liée à

table2_col1 = models.OneToOneField(table1,on_delete=models.CASCADE, related_name='table1_id')

table2 ne contiendra qu'un seul enregistrement correspondant à la valeur pk de table1, c'est-à-dire que table2_col1 aura une valeur unique égale au pk de la table.

table2_col1 == models.ForeignKey(table1, on_delete=models.CASCADE, related_name='table1_id')

table2 peut contenir plus d'un enregistrement correspondant à la valeur pk de table1.

1voto

T. Ems Points 21

Le moyen le plus simple d'établir une relation entre des éléments est de les comprendre en langage clair. Exemple

Un utilisateur peut avoir plusieurs voitures, mais une voiture ne peut avoir qu'un seul propriétaire. Après avoir établi cela, la clé étrangère doit être utilisée sur l'élément avec la relation many. Dans ce cas, la voiture. Ce qui signifie que vous allez inclure l'utilisateur comme clé étrangère dans les voitures.

Et une relation en tête à tête est assez simple. Disons un homme et un coeur. Un homme n'a qu'un seul cœur et un cœur ne peut appartenir qu'à un seul homme.

1voto

Siva Sankar Points 770

OneToOneField (exemple : une voiture a un propriétaire) ForeignKey(OneToMany) (Exemple : un restaurant a plusieurs articles)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X