2016-02-05 21 views
9

W aplikacji, nad którą pracuję, próbuję udostępnić tokeny dostępu w firmie. Przykład: lokalne biuro może wykorzystać tokeny centrali, aby opublikować coś na swojej stronie na Facebooku.Django: GenericForeignKey i unique_together

Ponieważ Facebook, Twitter i inne serwisy społecznościowe obsługują tokeny dostępu na swój własny sposób, stworzyłem i streszczenie klasy AccessToken. Każda witryna otrzymuje własną klasę, np.

class FacebookAccessToken(AccessToken): 
    # class stuff 

Po jakiejś lektury dowiedziałam się, że muszę użyć GenericForeignKey pkt do klas, które dziedziczą AccessToken. Zrobiłem następujące klasy:

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')) 

Kiedy uruchomić serwera testowego django pojawia się następujący błąd:

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.

Nie rozumiem, dlaczego ten błąd, po raz pierwszy za pomocą GenericForeignKey. Co ja robię źle?

Jeśli istnieje inteligentniejszy sposób udostępniania tokenów dostępu, chciałbym o tym usłyszeć.

Odpowiedz

11

Twoje użycie ogólnego klucza obcego w tej sytuacji jest poprawne.

Błąd pochodzi z deklaracji unique_together w modelu. unique_together można używać tylko z kolumnami istniejącymi w bazie danych. Ponieważ contentObject nie jest prawdziwą kolumną, Django skarży się na ograniczenie.

Zamiast tego, można wykonać następujące czynności:

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

Jest to równoznaczne z tym, co określiła w swoim pytaniu, ponieważ contentObject jest naprawdę tylko połączenie contentType i contentId za kulisami.

+0

Dziękuję za odpowiedź. – CyberFly

+0

Myślę, że miałeś na myśli 'objectId' zamiast' contentId'. –