2010-07-11 3 views
29

Ich finde widersprüchliche Informationen darüber, ob OneToOneField (User) oder ForeignKey (User, unique = True) beim Erstellen eines UserProfile-Modells durch Erweitern des Django-Benutzermodells verwendet werden soll.Django: Wenn Benutzer erweitert wird, besser OneToOneField (User) oder ForeignKey (User, unique = True) zu verwenden?

Ist es besser, zu verwenden, um dies ?:

class UserProfile(models.Model): 
    user = models.ForeignKey(User, unique=True) 

oder das ?:

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 

Die Django Doc gibt OneToOneField, während der Django Book example ForeignKey verwendet.

James Bennett hat auch zwei Blog-Artikel, dass die Bereitstellung widersprüchliche Beispiele auch:

In der ehemaligen Post stellt Bennett einige Gründe, warum er stattdessen mit ForeignKey geschaltet von OneToOneField, aber ich verstehe es nicht ganz, besonders wenn ich andere Beiträge sehe, die das Gegenteil empfehlen.

Ich bin gespannt auf Ihre Präferenz und warum. Oder spielt es überhaupt eine Rolle?

+0

Ich sehe nichts in Bennetts ersten Artikel über Benutzerprofile. –

+0

@Ignacio - Entschuldigung, ich habe einen Link zum falschen Artikel hinzugefügt. Es hätte zu seinem Beitrag über "Erweiterung des Nutzermodells" kommen sollen. Ich habe den Link korrigiert. Danke, dass du darauf hingewiesen hast. –

+0

Für mich ist http://stackoverflow.com/questions/5870537/whats-the-difference-between-django-onetoonefield-and-foreignkey klarer zu verstehen –

Antwort

17

Der einzige wirkliche Grund in dem Artikel ist, dass es so eingerichtet werden kann, dass die Admin-Seite für User beide Felder in User und UserProfile zeigt. Dies kann mit einem OneToOneField mit ein wenig Ellenbogenfett repliziert werden, es sei denn, Sie süchtig danach, es auf der Admin-Seite ohne Arbeit auf Kosten von ein wenig Klarheit zu zeigen ("Wir können mehrere Profile pro Benutzer erstellen ?! Oh nein Warte, es ist einzigartig. ") Ich würde OneToOneField verwenden.

7

Ein weiterer Grund für die ForeignKey Lösung neben den Admin-Seitenzeilen ist, dass Sie den richtigen Standard-DB-Manager verwenden können, wenn auf Objekte mit einer umgekehrten Beziehung zugegriffen wird. Betrachten Sie ein Beispiel aus dieser subclasses manager snippet. Lassen Sie uns sagen, dass die Post Klassendefinition aus dem Beispiel wie folgt aussieht:

class Post(ParentModel): 
    title = models.CharField(max_length=50) 
    onetoone = models.ForeignKey(SomeModel, unique=True) 

    children = ChildManager() 
    objects = models.Manager() 

Durch den Aufruf somemodel_instance.post_set.all()[0] Sie die gewünschten Unterklassen Objekte der Post Klasse erhalten, wie durch die Definition der ersten (Standard) Manager als ChildManager angegeben. Auf der anderen Seite, mit OneToOneField, durch den Aufruf somemodel_instance.post erhalten Sie die Post Klasseninstanz. Sie können immer somemodel_instance.post.subclass_object anrufen und erhalten das gleiche Ergebnis, aber der Standard-Manager könnte jede andere Art von Tricks und die FK Lösungen versteckt sie schön.

Wenn Sie besitzen und den benutzerdefinierten Manager-Code ändern können, können Sie das Attribut use_for_related_fields anstelle von FK anstelle von legitimen 1to1 Feld verwenden, aber auch das kann wegen einiger mir nicht bekannten Ärgernisse der automatischen Manager fehlschlagen. Soweit ich mich erinnere, wird es im obigen Beispiel scheitern.

5

anderer Grund im Allgemeinen nicht benutzt die OneToOneField bezogenen Beziehungen umgekehrt: wenn Sie die Rückwärts Beziehungen verwenden definiert über OneToOneField Sie erhalten eine Modellinstanz, im Gegensatz zu Manager für ForeignKey umgekehrte Beziehung und als Folge gibt es immer eine DB getroffen.Dies ist teuer, wenn Sie generische Sachen in umgekehrten Beziehungen (über _meta.get_all_related_objects()) tun und nicht wissen und sich darum kümmern, ob Sie sie alle verwenden werden oder nicht.

Verwandte Themen