Quelle est la différence entre Django OneToOneField
y ForeignKey
?
Réponses
Trop de publicités?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.
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.
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.
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.