2010-03-22 13 views
15

Ecco una versione semplificata di uno dei miei modelli:Perché l'admin di django non accetta chiavi esterne Nullable?

class ImportRule(models.Model): 
    feed = models.ForeignKey(Feed) 
    name = models.CharField(max_length=255) 
    feed_provider_category = models.ForeignKey(FeedProviderCategory, null=True) 
    target_subcategories = models.ManyToManyField(Subcategory) 

Questa classe gestisce una regola per l'importazione di un elenco di elementi da un feed nel database.

Il sistema di amministrazione non mi consente di aggiungere una ImportRule senza selezionare un feed_provider_category nonostante sia dichiarato nel modello come annullabile. La banca dati (SQLite al momento) controlla anche fuori ok:

>>> .schema 
... 
CREATE TABLE "someapp_importrule" (
    "id" integer NOT NULL PRIMARY KEY, 
    "feed_id" integer NOT NULL REFERENCES "someapp_feed" ("id"), 
    "name" varchar(255) NOT NULL, 
    "feed_provider_category_id" integer REFERENCES "someapp_feedprovidercategory" ("id"), 
); 
... 

posso creare l'oggetto nella shell python abbastanza facilmente:

f = Feed.objects.get(pk=1) 
i = ImportRule(name='test', feed=f) 
i.save() 

... ma il sistema di amministrazione non permetterà lo modifico, ovviamente. Come posso far sì che l'amministratore mi consenta di modificare/creare oggetti senza specificare quella chiave esterna?

risposta

32

Che ne dici di blank = True? Da Django's docs:

Se un campo ha spazio = Vero, la convalida sul sito di amministrazione di Django consentirà l'inserimento di un valore vuoto. Se un campo è vuoto = Falso, il campo sarà richiesto.

+2

che ha funzionato. Stavo pensando che null = True sarebbe stato sufficiente se non fosse un CharField, e che blank = True fosse specifico di CharField. Sembra che mi sbagliavo. –

+1

Questo mi ha fatto chiedere, perché l'amministratore di Django non consente automaticamente valori vuoti per i campi null = True senza impostazione esplicita vuota = True? Troppa magia? – jholster

+4

'null = True' funziona per il modello (database), mentre' blank = True' è per il modulo. C'è un'altra scelta per le forme: 'editable = False' – jpaugh

2

... ok, ho scoperto come farlo da solo. Potrebbe non essere il modo migliore, ma ho creato un modulo personalizzato per validare il modello:

class AdminImportRuleForm(forms.ModelForm): 
    class Meta: 
    model = ImportRule 
    name = forms.CharField(max_length=255) 
    feed = forms.ModelChoiceField(required=True, queryset=Feed.objects.all()) 
    feed_provider_category = forms.ModelChoiceField(required=False, queryset=FeedProviderCategory.objects.all()) 
    target_subcategories = forms.ModelMultipleChoiceField(queryset=Subcategory.objects.all()) 

E ho legato in classe Admin:

class ImportRuleAdmin(admin.ModelAdmin): 
    form = AdminImportRuleForm 
    ... 

questo ha preso un sacco di lavoro fuori e un sacco di inutili fastidi, quindi se qualcun altro ha una soluzione migliore ottengono voti/accetta/qualunque cosa mi consenta di dare :)

5

Si dovrebbe provare ad aggiungere nulla = True, come questo:

car = models.ForeignKey(Car, default=None, null=True, blank=True) 
Problemi correlati