2009-06-02 9 views

risposta

4

Se si utilizza la versione di sviluppo di Django, è possibile implementare il metodo formfield_for_foreignkey() su AdminModel per impostare un valore predefinito.

25
class Foo(models.Model): 
    a = models.CharField(max_length=42) 

class Bar(models.Model): 
    b = models.CharField(max_length=42) 
    a = models.ForeignKey(Foo, default=lambda: Foo.objects.get(id=1)) 
+0

Sei lo stesso ragazzo di questo articolo? In caso contrario, considera l'aggiunta del link. http://djangodays.com/2009/05/11/django-foreign-key-default-value-example/ – Paolo

+0

L'utilizzo di nomi di simboli nei modelli per i valori predefiniti è piuttosto comune. Non ricordo il sito, ma ho cambiato lo snippet in uno schema più breve. –

+0

Questa dovrebbe essere la risposta accettata. – dhilipsiva

1

Quanto a me, per Django 1.7 il suo lavoro, solo pk:

category = models.ForeignKey(Category, editable=False, default=1)

ma ricordate, che la migrazione sembra

migrations.AlterField(
      model_name='item', 
      name='category', 
      field=models.ForeignKey(default=1, editable=False, to='item.Category'), 
      preserve_default=True, 
     ), 

così, non credo deve funzionare con l'utente dinamico pk.

-2
class table1(models.Model): 
    id = models.AutoField(primary_key=True) 
    agentname = models.CharField(max_length=20) 

class table1(models.Model): 
    id = models.AutoField(primary_key=True) 
    lastname = models.CharField(max_length=20) 
    table1 = models.ForeignKey(Property) 
+0

Si prega di aggiungere alcune spiegazioni al codice, perché questo risponde alla domanda? – MeanGreen

0
def get_user_default_id(): 
    return 1 

created_by = models.ForeignKey(User, default=get_user_default_id) 
+0

aggiungi anche qualche descrizione. –

7

Ecco una soluzione che funzionerà in Django 1.7. Invece di fornire il default alla definizione del campo, impostarla come null-grado, ma overide la funzione 'Salva' per riempire la prima volta (mentre è null):

class Foo(models.Model): 
    a = models.CharField(max_length=42) 

class Bar(models.Model): 
    b = models.CharField(max_length=42) 
    a = models.ForeignKey(Foo, null=True) 

    def save(self, *args, **kwargs): 
     if self.a is None: # Set default reference 
      self.a = Foo.objects.get(id=1) 
     super(Bar, self).save(*args, **kwargs) 
+0

Hai davvero bisogno di rendere nulla il campo? Penso che l'oggetto non sia ancora stato salvato, cioè. non ha ancora id, non è "pulito" a meno che non si metta "full_clean" prima del super (.. save .. Quindi cambierei la condizione in se self.id è None: e dovrebbe funzionare senza null = True –

+0

@MilanoSlesarik potresti avere ragione, il motivo per cui l'ho messo lì in primo luogo, è perché era un nuovo campo che ho aggiunto a un modello esistente (con righe di record esistenti), e quindi dovevo permetterlo di essere null –

+0

@o_c Non è una buona idea dato che save (..) non viene chiamato da QuerySet di aggiornamento batch .. a meno che non si esegua un loop in modo esplicito su ogni elemento restituito e si chiami save, che quindi vanifica lo scopo di utilizzare un aggiornamento batch in primo luogo (e gli sviluppatori tendono a dimenticare) – strangetimes

2

Ho fatto questo allo stesso modo di @o_c, ma preferisco usare get_or_create piuttosto che semplicemente pk.

class UserSettings(models.Model): 
    name = models.CharField(max_length=64, unique=True) 
    # ... some other fields 

    @staticmethod 
    def get_default_user_settings(): 
     user_settings, created = UserSettings.objects.get_or_create(
      name = 'Default settings' 
     ) 
     return user_settings 

class SiteUser(...): 
    # ... some other fields 

    user_settings = models.ForeignKey(
     to=UserSettings, 
     on_delete=models.SET_NULL, 
     null=True 
    ) 

    def save(self, *args, **kwargs): 
     if self.user_settings is None: 
      self.user_settings = UserSettings.get_default_params() 
     super(SiteUser, self).save(*args, **kwargs) 
+0

Questa risposta dovrebbe essere più alta, perché è semplice e intelligente. –

1

Questa è una leggera modifica alla risposta da o_c. Dovrebbe salvarti un colpo nel database. Nota nel metodo di salvataggio, utilizzo self.a_id = 1 invece di self.a = Foo.objects.get (id = 1). Ha lo stesso effetto senza dover interrogare Foo.

class Foo(models.Model): 
    a = models.CharField(max_length=42) 

class Bar(models.Model): 
    b = models.CharField(max_length=42) 
    a = models.ForeignKey(Foo, null=True) 

    def save(self, *args, **kwargs): 
     if self.a is None: # Set default reference 
      self.a_id = 1 
     super(Bar, self).save(*args, **kwargs) 
5

per Django 1.7 o superiore,

Basta creare un oggetto ForeignKey e salvarlo. Il valore "predefinito" può essere l'id dell'oggetto che deve essere collegato per impostazione predefinita.

Per esempio,

created_by = models.ForeignKey(User, default=1) 
Problemi correlati