2010-03-22 6 views
15

ist hier eine vereinfachte Version eines meiner Modelle:Warum akzeptiert der Django-Administrator keine Nullable-Fremdschlüssel?

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) 

Diese Klasse verwaltet eine Regel eine Liste von Elementen aus einem Feed in die Datenbank für den Import.

Das Admin-System lässt mich keine ImportRule hinzufügen, ohne eine feed_provider_category auszuwählen, obwohl sie im Modell als nullable deklariert ist. Die Datenbank (SQLite im Moment) prüft sogar aus ok: wird nicht zulassen,

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

... aber das Admin-System

:

>>> .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"), 
); 
... 

ich das Objekt in dem Python-Shell erstellen kann leicht genug ich bearbeite es natürlich. Wie kann ich den Administrator veranlassen, dass ich Objekte bearbeiten/erstellen kann, ohne diesen Fremdschlüssel anzugeben?

Antwort

32

Wie wäre es mit blank = True? Von Django's docs:

:

Wenn ein Feld leer = True ist, erlaubt die Validierung auf Djangos Admin-Site die Eingabe eines leeren Wertes. Wenn ein Feld leer = False ist, wird das Feld benötigt.

+2

Das funktionierte. Ich dachte, dass null = True genug wäre, wenn es kein CharField wäre, und dass blank = True CharField-spezifisch war. Sieht so aus, als hätte ich mich geirrt. –

+1

Das hat mich neugierig gemacht, warum Djangos Admin nicht automatisch leere Werte für null = True-Felder erlaubt, ohne explizit Leerzeichen zu setzen = True? Zu viel Magie? – jholster

+4

'null = True' funktioniert für das Modell (Datenbank), während' blank = True' für das Formular gilt. Es gibt eine andere Auswahl für Formulare: 'editable = False' – jpaugh

2

... ok, ich habe herausgefunden, wie ich das alleine machen kann. Es ist vielleicht nicht der beste Weg sein, aber ich erstellt ein benutzerdefiniertes Formular, das Modell zu validieren:

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()) 

Und ich es in die Admin-Klasse verknüpft:

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

Dies hat eine Menge Arbeit und eine Menge unnötiger Ärger, also wenn jemand anderes eine bessere Lösung hat, bekommen sie Votum-ups/akzeptiert/was auch immer es mir lassen wird :)

5

sollten Sie versuchen, null Hinzufügen = True, wie diese:

car = models.ForeignKey(Car, default=None, null=True, blank=True) 
Verwandte Themen