列出Django ModelAdmin中的相关字段 [英] Listing Related Fields in Django ModelAdmin

查看:124
本文介绍了列出Django ModelAdmin中的相关字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  class MyRelatedModel(models.Model)
name = models.CharField(max_length = 50)
创建= 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']

但是,使用other__name会抛出错误配置错误:

 'MyRelatedModelInline.fields'指的是从

中缺少的other__name字段在ModelAdmin中不支持模型遍历语法实例?如果支持,我做错了什么?



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

 渲染时捕获AttributeError:'MyMainModelAdmin'对象没有属性'__name__'


解决方案

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



models.py:

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

class Employee(models。模型)
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)

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)

de f model_admin_callable(self,emp):
return emp.car.rego

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

admin.site.register(Company,CompanyAdmin)

当你可以看到,readonly_fields的处理方式与list_display的方式一样,根据contrib.admin的Django文档(从1.2开始)。



在上述示例中,当您编辑公司时,您将看到其员工内联。每行将在可编辑的文本框中具有一个员工名称,并在该名称旁边显示该员工的车辆(emp.car.rego)的只读文本。



参考您的原始问题,您想将相关数据引用为other__name。这不行。在运行Django查询时,诸如 other__name car__rego 的表达式在筛选器中只具有特殊含义作为关键字参数。例如,当获取具有特定号码的汽车的员工时:

  Employee.objects.filter(car__rego =' 111')

希望有所帮助。



j


I'm listing a model in Django's admin via a TabularInline. Inside this inline, I'd like to use Django's model traversal syntax to list data in other models referenced in the model via foreign keys. e.g.

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']

However, the usage of 'other__name' throws the ImproperlyConfigured error:

'MyRelatedModelInline.fields' refers to field 'other__name' that is missing from the form

Is the model traversal syntax not supported in ModelAdmin instances? If it is supported, what am I doing wrong?

EDIT: If I uncomment readonly_fields, the error becomes:

Caught AttributeError while rendering: 'MyMainModelAdmin' object has no attribute '__name__'

解决方案

As per Roseman's suggestion above, you can display related (one-to-one or many-to-one) data in a readonly manner with Inline admin models. Here's a little example, just to make sure that we are all on the same page. You can see below that there are three ways to achieve your goal (if I understand that goal correctly).

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)

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)

As you can see, 'readonly_fields' is treated in the same manner as 'list_display' as per the Django documentation for contrib.admin (from 1.2 onwards).

In the above example, when you are editing a Company, you will see its employees inlined. Each row will have an employee name in an editable textbox and next to the name you will see a readonly bit of text for the employee's car's rego (emp.car.rego).

Referring to your original question, you wanted to reference the related data as 'other__name'. This won't work. Expressions like other__name or car__rego only have special meaning as keyword arguments in filters when running Django queries. For example, when fetching an employee who has a car with a particular rego number:

Employee.objects.filter(car__rego='111')

Hope that helps.

j

这篇关于列出Django ModelAdmin中的相关字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆