2016-02-05 13 views
9

Nell'applicazione a cui sto lavorando Sto tentando di condividere i token di accesso all'interno di un'azienda. Esempio: un ufficio locale può utilizzare i token della sede centrale per pubblicare qualcosa sulla loro pagina Facebook.Django: GenericForeignKey e unique_together

class AccessToken(models.Model): 
    """Abstract class for Access tokens.""" 
    owner = models.ForeignKey('publish.Publisher') 
    socialMediaChannel = models.IntegerField(
     choices=socialMediaChannelList, null=False, blank=False 
    ) 
    lastUpdate = models.DateField(auto_now=True) 

    class Meta: 
     abstract = True 

Dal momento che Facebook, Twitter e altri siti di social media gestire token di accesso a modo loro feci e classe astratta access token. Ogni sito riceve la propria classe, ad es.

class FacebookAccessToken(AccessToken): 
    # class stuff 

Dopo aver fatto qualche lettura ho scoperto che devo usare un GenericForeignKey per puntare a classi che ereditano AccessToken. Ho fatto la seguente classe:

class ShareAccessToken(models.Model): 
    """Share access tokens with other publishers.""" 
    sharedWith = models.ForeignKey('publish.Publisher') 
    sharedBy = models.ForeignKey(User) 

    # for foreignkey to abstract model's children 
    contentType = models.ForeignKey(ContentType) 
    objectId = models.PositiveIntegerField() 
    contentObject = GenericForeignKey('contentType', 'objectId') 

    class Meta: 
     unique_together = (('contentObject', 'sharedWith')) 

Quando eseguo il server di test Django ottengo il seguente errore:

core.ShareAccessToken: (models.E016) 'unique_together' refers to field 'contentObject' which is not local to model 'ShareAccessToken'. HINT: This issue may be caused by multi-table inheritance.

Non capisco perché ottengo questo errore, prima volta con GenericForeignKey. Che cosa sto facendo di sbagliato?

Se esiste un modo più intelligente per condividere i token di accesso, mi piacerebbe saperlo.

risposta

11

L'utilizzo della chiave esterna generica in questa situazione è corretto.

L'errore viene dalla dichiarazione unique_together nel modello. unique_together può essere utilizzato solo con le colonne presenti nel database. Dal momento che contentObject non è una vera colonna, Django si lamenta del vincolo.

Invece, è possibile effettuare le seguenti operazioni:

unique_together = (('contentType', 'contentId', 'sharedWidth'),) 

Questo è equivalente a quello che aveva definito nella domanda, perché contentObject è in realtà solo la combinazione di contentType e contentId dietro le quinte.

+0

Grazie per la risposta. – CyberFly

+0

Penso che intendessi 'objectId' invece di' contentId'. –