2012-01-21 15 views
8

Sto cercando di capire come disporre due dei miei modelli Django in modo che quando un nuovo modello viene salvato nel database, la sua chiave primaria viene incrementata in modo tale che sia il successivo valore più alto per tutti i record con la stessa chiave esterna.Modello Django Incremento automatico Chiave primaria basata su chiave esterna

È molto simile a this question asked, ma mi chiedo come lo faresti in Django. Ecco un estratto dalla questione che dimostra una situazione simile:

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

So you can't have multiple primary keys in a Django model e si può usare unique_together, ma la documentazione dice che usa l'equivalente UNIQUE economico nei CREATE dichiarazioni. Sarebbe

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

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

nei modelli lavorare con this answer per realizzare quello che sto cercando? Il rapporto tra i modelli è uno ModelA con molti ModelB s, ma ogni ModelB dispone di un solo ModelA.

+1

Questo primo paragrafo non è stato analizzato. –

+0

@ IgnacioVazquez-Abrams, ho riformulato il primo paragrafo e aggiunto un esempio. Ha più senso ora? – Dirk

risposta

8

Dirk, è necessario apportare alcune modifiche al modello (se consentito) come Ignacio ha detto. Quindi, ModelA dovrebbe ora assomigliare a quanto segue.

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) 

Come potete vedere, ho overridden the default save method di calcolare il valore della chiave da un metodo cal_key prendendo fk as argument. Quindi, definire il seguente metodo cal_key nel file dei modelli.

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 

Il metodo cal_key indica chiaramente ciò che effettivamente richiede.

+0

Grazie Sandip. Sono andato con la tua risposta perché era più portatile della risposta di Ignacio. – Dirk

+0

Se l'applicazione è multi-thread, è possibile che questa soluzione possa generare l'errore di convalida unique_together perché tenta di allocare la stessa chiave a due funzioni diverse, se vengono salvate nello stesso momento? –

0

si può provare questo:

AutoFile 

si possono trovare here per i dettagli.

Problemi correlati