2010-01-05 13 views
10

Mam następujący model:Django: Sprawdź, czy atrybut klucz obcy jest ustawiona

class A(models.Model): 
    name = models.CharField(max_length=50) 
    content_type = models.ForeignKey(ContentType) 

Model ten ma być model korzeń w jakimś drzewie dziedziczenia i content_type atrybutem jest pewnego rodzaju wskazówkę co do typu jest naprawdę przechowywany. Oczywiście powinienem przeliczyć content_type przezroczyście po utworzeniu instancji. Myślę, że w __init__. Ale jest problem - istnieją dwa główne konteksty, w których przypadki są tworzone:

  1. a = A(name='asdfdf') # here we must fill in content_type
  2. przez QuerySet maszyny z *args krotki. W tym przypadku nie należy wypełnić content_type

Tak, ja staram się napisać:

def __init__(self, *args, **kwargs): 
    super(A, self).__init__(*args, **kwargs) 
    if self.content_type is None: # << here is the problem 
     self.content_type = ContentType.objects.get_for_model(self) 

Rzecz self.content_type jest ReverseSingleRelatedObjectDescriptor wystąpienie z __get__ nadpisane tak, że rzuca się wartość sprawa jest nie ustawiony. Tak, mogę wykonać następujące czynności:

def __init__(self, *args, **kwargs): 
    super(A, self).__init__(*args, **kwargs) 
    try: 
     self.content_type 
    except Exception, v: 
     self.content_type = ContentType.objects.get_for_model(self) 

Ale nie podoba mi się to. Czy istnieje bardziej "grzeczny" sposób sprawdzania, czy ustawiony jest atrybut ForeignKey?

+0

Po pierwsze, jeśli chcesz, aby parametr 'content_type' był opcjonalny, myślę, że będziesz musiał ustawić' blank = True, null = True' w swojej definicji pola. –

+1

Nie chcę, aby była opcjonalna, po prostu nie chcę ustawiać jej wartości, jeśli została już ustawiona przez Django (w procesie czytania z DB). –

Odpowiedz

29

Czy to działa, jeśli przejrzysz self.content_type_id zamiast self.content_type?

+0

Z pewnością masz rację. Dokładnie tego potrzebuję. Dziękuję Ci. –