在Django ModelAdmin中列出相关字段

Cer*_*rin 6 python django django-admin

我通过TabularInline在Django的管理员中列出了一个模型.在这个内联中,我想使用Django的模型遍历语法来列出模型中通过外键引用的其他模型中的数据.例如

class MyRelatedModel(models.Model)
    name = models.CharField(max_length=50)
    created = models.DateField(auto_now_add=True)
    other = models.ForeignKey('MyOtherRelatedModel')

class MyOtherRelatedModel(models.Model)
    name = models.CharField(max_length=50)
    created = models.DateField(auto_now_add=True)

class MyRelatedModelInline(admin.TabularInline):
    model = MyRelatedModel
    fields = ['name', 'created', 'other__name']
    #readonly_fields = ['name', 'created', 'other__name']
Run Code Online (Sandbox Code Playgroud)

但是,'other__name'的使用会引发ImproperlyConfigured错误:

'MyRelatedModelInline.fields' refers to field 'other__name' that is missing from the form
Run Code Online (Sandbox Code Playgroud)

ModelAdmin实例中是否不支持模型遍历语法?如果它得到支持,我做错了什么?

编辑:如果我取消注释readonly_fields,错误变为:

Caught AttributeError while rendering: 'MyMainModelAdmin' object has no attribute '__name__'
Run Code Online (Sandbox Code Playgroud)

jsw*_*jsw 17

根据Roseman上面的建议,您可以使用Inline管理模型以只读方式显示相关(一对一或多对一)数据.这是一个小例子,只是为了确保我们都在同一页面上.您可以在下面看到,有三种方法可以实现您的目标(如果我正确理解了目标).

models.py:

class Company(models.Model):
    name = models.CharField(max_length=50)

class Employee(models.Model):
    name = models.CharField(max_length=50)
    company = models.ForeignKey('Company')
    car = models.ForeignKey('Car')

    def model_callable(self):
        return self.car.rego

class Car(models.Model):
    rego = models.CharField(max_length=50)
Run Code Online (Sandbox Code Playgroud)

admin.py:

def unbound_callable(emp):
    return emp.car.rego

class EmployeeInline(admin.TabularInline):
    model = Employee
    fields = ('name', 'model_callable', 'model_admin_callable', unbound_callable)
    readonly_fields = ('model_callable', 'model_admin_callable', unbound_callable)

    def model_admin_callable(self, emp):
        return emp.car.rego

class CompanyAdmin(admin.ModelAdmin):
    model = Company
    inlines = (EmployeeInline,)

admin.site.register(Company, CompanyAdmin)
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,'readonly_fields'的处理方式与'list_display'相同,符合contrib.admin的Django文档(从1.2开始).

在上面的示例中,当您编辑公司时,您将看到其内联员工.每行在可编辑的文本框中都有一个员工姓名,在名称旁边,您将看到员工汽车的rego(emp.car.rego)的一些文本.

参考您的原始问题,您希望将相关数据引用为"other__name".这不行.运行Django查询时,表达式中的表达式类似于other__namecar__rego仅具有特殊含义作为关键字参数.例如,在提取拥有特定条件号的汽车的员工时:

Employee.objects.filter(car__rego='111')
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.

Ĵ