Django管理员列表显示+ForeignKey = 空更改列表

7

我在Django管理页面的list_display中遇到了一个奇怪的问题。每当我将外键添加到list_display中时,整个变更列表视图都会变空,仅显示条目的总数。

models.py:

class Organization(models.Model):
    org_id = models.AutoField(primary_key=True)
    org_name = models.CharField(max_length=288)

    def __unicode__(self):
        return self.org_name

    class Meta:
        db_table = u'organization'

class Server(models.Model):
    server_id = models.AutoField(primary_key=True)
    server_name = models.CharField(max_length=135,verbose_name="Server Name")
    org = models.ForeignKey(Organization,verbose_name="Organization")   

    def __unicode__(self):
        return self.server_name

    class Meta:
        db_table = u'server'

admin.py:

class ServerAdmin(admin.ModelAdmin):
    list_display = ('server_name','org') 
admin.site.register(Server,ServerAdmin) 

现在我期望这段代码可以在ChangeList视图中显示组织名称,但是我得到了下面这个结果:
如果我在ServerAdmin类的list_display中移除org,我会得到下面这个结果:
我没有修改模板或覆盖任何ModelAdmin方法。我使用的是Ubuntu 11.10仓库提供的Mysql(5.1.58)作为我的数据库。
如果能够解决这个问题,我将非常感激。谢谢!

models.py 中我看到 TlxServer,而在 admin.py 中只有 Server。这是打字错误吗? - jcollado
你不需要定义一个AutoField。Django会自动为每个表创建一个主键。 - dan-klasson
@jcollado:那是个打字错误 :P 应该是“服务器” - Pannu
@dan-klasson:我从一个旧数据库中获取了模型。我运行了 inspectdb 命令,得到了这些模型,并且我发现主键是 IntegerField 类型,所以我将它们改为了 AutoField - Pannu
4个回答

8
我同意Stefano的观点,应该添加"null=True, blank=True"。但是,我认为你只需要将其添加到Organization模型的org_name字段中即可。这样就可以解决问题了。必须这样做,因为你已经运行了inspectdb来从旧数据库创建模型。可能在数据库中的organization表中存储了一个空字符串。因此,添加上述内容将允许管理员显示一个空白的字段/列。
此外,在不想更改模型定义的情况下,您还可以尝试在某些情况下使用callbacks

好的!我遇到了另一个模型类似于“Organization”,它有一个指向“User”的“ForeignKey”。多亏了你和“django-debug-toolbar”,我找到了导致整个问题的“INNER JOINS”。 “inspectdb”没有指定“null=True, blank=True”,而我太懒了,没有交叉检查模型和数据库。谢谢你,我欠你一个人情,解决了这个看起来神秘的问题。 - Pannu
任何时候,Pannu。大家都在这里学习,我也从你的问题中学到了东西。 - Sandip Agarwal

3
尝试在所有模型字段中添加null=True, blank=True。通常情况下,如果行未验证模型约束条件,则Django管理界面将悄悄失败(因此不会显示任何记录)。

2

请参见:https://dev59.com/83VC5IYBdhLWcg3w2lCI#163968

以下内容是否适用于您?

admin.py:

class ServerAdmin(admin.ModelAdmin):
    list_display = ('server_name','org__org_name') 
admin.site.register(Server,ServerAdmin) 

我尝试了你的解决方案,虽然听起来很奇怪,但似乎并没有起作用。它一直弹出一个错误:“'org__org_name'不是'ServerAdmin'的可调用或属性,也没有在模型'Server'中找到。”无论如何还是谢谢你啊。 - Pannu
在list_display中,您不能使用跨关系的术语,这可能非常有帮助。解决方法是在ModelAdmin子类中定义一个方法,返回您要查找的值,并将该方法的名称添加到list_display中。 - glarrain

1
我遇到过类似的问题,并按照以下方式解决了它(使用您的示例):
class ServerAdmin(admin.ModelAdmin):
    list_display = ('server_name', 'get_org') 

    def get_org(self, obj):
        return obj.org.org_name

    get_org.short_description = 'Org'

admin.site.register(Server,ServerAdmin)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接