ForeignKey field will not appear in Django admin s

2019-08-02 20:06发布

A foreign key on a model is not appearing in the Django admin site. This is irrespective of whether the field is explicitly specified in a ModelAdmin instance (fields = ('title', 'field-that-does-not-show-up')) or not.

I realize there are many variables that could be causing this behavior.

class AdvertiserAdmin(admin.ModelAdmin):
    search_fields = ['company_name', 'website']
    list_display = ['company_name', 'website', 'user']


class AdBaseAdmin(admin.ModelAdmin):
    list_display = ['title', 'url', 'advertiser', 'since', 'updated', 'enabled']
    list_filter = ['updated', 'enabled', 'since', 'updated', 'zone']
    search_fields = ['title', 'url']

The problem is the advertiser foreign key is not showing up in the admin for AdBase

class Advertiser(models.Model):
    """ A Model for our Advertiser
    """
    company_name = models.CharField(max_length=255)
    website = models.URLField(verify_exists=True)
    user = models.ForeignKey(User)

    def __unicode__(self):
        return "%s" % self.company_name

    def get_website_url(self):
        return "%s" % self.website

class AdBase(models.Model):
    """
    This is our base model, from which all ads will inherit.
    The manager methods for this model will determine which ads to
    display return etc.

    """
    title = models.CharField(max_length=255)
    url = models.URLField(verify_exists=True)
    enabled = models.BooleanField(default=False)
    since = models.DateTimeField(default=datetime.now)
    expires_on=models.DateTimeField(_('Expires on'), blank=True, null=True)
    updated = models.DateTimeField(editable=False)

    # Relations
    advertiser = models.ForeignKey(Advertiser)
    category = models.ForeignKey(AdCategory)
    zone = models.ForeignKey(AdZone)

    # Our Custom Manager
    objects = AdManager()

    def __unicode__(self):
        return "%s" % self.title

    @models.permalink
    def get_absolute_url(self):
        return ('adzone_ad_view', [self.id])

    def save(self, *args, **kwargs):
        self.updated = datetime.now()
        super(AdBase, self).save(*args, **kwargs)

    def impressions(self, start=None, end=None):
        if start is not None:
            start_q=models.Q(impression_date__gte=start)
        else:
            start_q=models.Q()
        if end is not None:
            end_q=models.Q(impression_date__lte=end)
        else:
            end_q=models.Q()
        return self.adimpression_set.filter(start_q & end_q).count()

    def clicks(self, start=None, end=None):
        if start is not None:
            start_q=models.Q(click_date__gte=start)
        else:
            start_q=models.Q()
        if end is not None:
            end_q=models.Q(click_date__lte=end)
        else:
            end_q=models.Q()
        return self.adclick_set.filter(start_q & end_q).count()

class BannerAd(AdBase):
    """ A standard banner Ad """
    content = models.ImageField(upload_to="adzone/bannerads/")

The mystery deepens. I just tried to create a ModelForm object for both AdBase and BannerAd, and both generated fields for the advertiser. Some crazy admin things going on here...

8条回答
做个烂人
2楼-- · 2019-08-02 20:38

maybe it is an encode error. I had the same problem, but when i added # -- coding: UTF-8 -- in the models.py, all fine.

查看更多
forever°为你锁心
3楼-- · 2019-08-02 20:39

Try disabling your ad blocker. No, this is not a joke. I just ran into this exact problem.

查看更多
神经病院院长
4楼-- · 2019-08-02 20:42

It's a strange problem for sure. On the AdBase model if you change

advertiser = models.ForeignKey(Advertiser)

to

adver = models.ForeignKey(Advertiser)

then I believe it'll show up.

查看更多
Animai°情兽
5楼-- · 2019-08-02 20:46

I believe I've just run into exactly the same problem, but was able to debug it thanks to the help of persistent co-workers. :)

In short, if you look in the raw HTML source you'll find the field was always there - it's just that:

  • Django tries to be clever and put the form field inside a div with CSS class="form-row $FIELD_NAME",
  • The field's name was "advertiser", so the CSS class was "form-row advertiser",
  • ...Adblock Plus.

Adblock Plus will hide anything with the CSS class "advertiser", along with a hell of a lot of other CSS classes.

I consider this a bug in Django.

查看更多
乱世女痞
6楼-- · 2019-08-02 20:51

Powellc, do you have the models registered with their respective ModelAdmin class?

admin.site.register(Advertiser, AdvertiserAdmin) after the ModelAdmin definitions.

查看更多
闹够了就滚
7楼-- · 2019-08-02 20:52

Another very dumb cause of the same problem:

If there is only one instance of the related model, then the filter simply won't show. There is a has_output() method in RelatedFieldListFilter class that returns False in this case.

查看更多
登录 后发表回答