2012-01-21 12 views
8

Próbuję dowiedzieć się, jak rozmieścić dwa z moich modeli Django tak, że gdy nowy model zostanie zapisany do bazy danych, jego klucz podstawowy zostanie zwiększony tak, że jest następna najwyższa wartość dla wszystkich rekordów z tym samym kluczem obcym.Django Model Auto Increment Klucz podstawowy oparty na kluczu obcym

To bardzo przypomina this question asked, ale zastanawiam się, jak to zrobić w Django. Oto fragment z pytaniem, który wykazuje podobną sytuację:

id | job_id | title 
0  1  hi 
1  1  hello 
2  1  goodbye 
0  2  hi 
1  2  hello 

wiem you can't have multiple primary keys in a Django model i można korzystać unique_together, ale dokumentacja mówi, że używa się równoważnego UNIQUE oświadczenie w sprawozdaniu CREATE. Czy

class ModelA(models.Model): 
    key = models.PositiveIntegerField(primary_key = True) 
    fk = models.ForeignKey(ModelB) 

    def Meta(self): 
     unique_together = ("key", "fk") 

w modelach pracy z this answer do osiągnięcia co szukam? Relacja między modelami jest jednym ModelA mającym wiele ModelB s, ale każdy ModelB ma tylko jeden ModelA.

+1

Ten akapit pierwszy nie został przeanalizowany. –

+0

@ Ignacio Vaazquez-Abrams, Przeformułowałem akapit pierwszy i dodano przykład. Czy teraz ma to więcej sensu? – Dirk

Odpowiedz

8

Dirk, musisz dokonać pewnych zmian w modelu (jeśli jest to dopuszczalne), jak powiedział Ignacio. Tak więc ModelA powinien teraz wyglądać jak poniżej.

class ModelA(models.Model): 
    key = models.PositiveIntegerField() 
    fk = models.ForeignKey(ModelB) 

    def Meta(self): 
     unique_together = ("key", "fk") 

    def save(self, *args, **kwargs): 
     key = cal_key(self.fk) 
     self.key = key 
     super(ModelA, self).save(*args, **kwargs) 

Jak widać, mam overridden the default save method obliczyć wartość klucza z metody cal_key biorąc fk as argument. Zdefiniuj poniższą metodę cal_key w pliku modeli.

def cal_key(fk): 
    present_keys = ModelA.objects.filter(fk=fk).order_by('-key').values_list('key',flat=True) 
    if present_keys: 
     return present_keys[0]+1 
    else: 
     return 0 

Metoda jednoznacznie wskazuje, czego faktycznie potrzebujesz.

+0

Dzięki Sandip. Poszedłem z twoją odpowiedzią, ponieważ była bardziej przenośna niż odpowiedź Ignacio. – Dirk

+0

Jeśli twoja aplikacja jest wielowątkowa, czy to możliwe, że to rozwiązanie może podnieść błąd walidacji unique_together, ponieważ próbuje przydzielić ten sam klucz do dwóch różnych funkcji, jeśli są one zapisywane w tym samym czasie? –

0

można spróbować to:

AutoFile 

można znaleźć here szczegóły.