17

Here is a simplified version of one of my models:

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)

This class manages a rule for importing a list of items from a feed into the database.

The admin system won't let me add an ImportRule without selecting a feed_provider_category despite it being declared in the model as nullable. The database (SQLite at the moment) even checks out 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"),
);
...

I can create the object in the python shell easily enough:

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

...but the admin system won't let me edit it, of course. How can I get the admin to let me edit/create objects without specifying that foreign key?

p.g.l.hall
  • 1,961
  • 2
  • 15
  • 26

3 Answers3

43

How about blank=True? From Django's docs:

If True, the field is allowed to be blank. Default is False.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
jholster
  • 5,066
  • 1
  • 27
  • 20
  • 3
    That worked. I was thinking that null=True would be enough if it was not a CharField, and that blank=True was CharField-specific. Looks like I was wrong. – p.g.l.hall Mar 22 '10 at 16:07
  • 1
    This made me wondering, why Django's admin doesn't automatically allow blank values for null=True fields without explicitly setting blank=True? Too much magic? – jholster Mar 22 '10 at 16:12
  • 4
    `null=True` works for the model (database), while `blank=True` is for the form. There is another choice for forms: `editable=False` – jpaugh Jan 18 '12 at 15:20
5

You should try adding null=True, like this one:

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

...ok, I found out how to do this on my own. It might not be the best way, but I created a custom Form to validate the model:

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

And I linked it into the Admin class:

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

This took a lot of working out and a lot of unnecessary bother, so if anyone else has a better solution they get vote-ups/accepts/whatever it will let me give :)

p.g.l.hall
  • 1,961
  • 2
  • 15
  • 26