2012-03-30 14 views
16

Cosa c'è di diverso tra models.ForeignKey(Modelname, unique=True) e models.OneToOneField in Django?Differenza tra ForeignKey (Utente, unique = True) e OneToOneField

Dove dovrei usare models.OneToOneField e models.ForeignKey(Modelname, unique=True)?

+0

@alan Non sono stati sufficienti chiarimenti disponibili in altre risposte come questa Risposta di Alasdir chiarire molto bene il concetto – Hafiz

risposta

38

A OneToOneField è molto simile a ForeignKey con unique=True. A meno che non si stia eseguendo l'ereditarietà di più tabelle, nel qual caso è necessario utilizzare OneToOneField, l'unica vera differenza è l'API per l'accesso agli oggetti correlati.

Nel Django docs si dice:

Concettualmente, questo è simile a un ForeignKey con unique=True, ma il "rovescio" lato della relazione restituirà direttamente un singolo oggetto.

Mostriamo cosa significa questo con un esempio. Considera due modelli, Person e Address. Assumeremo che ogni persona abbia un indirizzo univoco.

class Person(models.Model): 
    name = models.CharField(max_length=50) 
    address = models.ForeignKey('Address', unique=True) 

class Address(models.Model): 
    street = models.CharField(max_length=50) 

Se si inizia con una persona, è possibile accedere all'indirizzo facilmente:

address = person.address 

Tuttavia, se si inizia con un indirizzo, devi andare via person_set manager per ottenere la persona.

person = address.person_set.get() # may raise Person.DoesNotExist 

Ora cerchiamo di sostituire il ForeignKey con un OneToOneField.

class Person(models.Model): 
    name = models.CharField(max_length=50) 
    address = models.OneToOneField('Address') 

class Address(models.Model): 
    street = models.CharField(max_length=50) 

Se si inizia con una persona, è possibile accedere all'indirizzo nello stesso modo:

address = person.address 

E ora, siamo in grado di accedere la persona con l'indirizzo più facilmente.

person = address.person # may raise Person.DoesNotExist 
+1

Penso che intendessi "indirizzo = modelli.ForeignKey (Address, unique = True)" nella classe Person. – alan

+0

@alan - buona cattura, ora riparata. – Alasdair

1

quando si accede a un OneToOneField si ottiene il valore del campo che si interrogato. In questo esempio, il campo 'titolo' di un modello di libro è un OneToOneField:

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

Quando si accede a un ForeignKey si ottiene l'oggetto del modello relativo, che è quindi possibile preforme ulteriori query. In questo esempio campo 'editore' lo stesso del modello di libro è un ForeignKey (correlazione alla definizione del modello Publisher classe):

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

Con ForeignKey campi query funzionano anche nel senso opposto, ma sono leggermente diversi a causa della natura non simmetrica della relazione.

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

Dietro le quinte, book_set è solo un QuerySet e possono essere filtrati e tagliati come qualsiasi altro QuerySet. Il nome attributo book_set viene generato aggiungendo il nome del modello minuscolo a _set. Spero che questo aiuti a illustrare le differenze tra le relazioni create.

Problemi correlati