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.
我通过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']
However, the usage of 'other__name' throws the ImproperlyConfigured error:
但是,'other__name'的使用会引发ImproperlyConfigured错误:
'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?
ModelAdmin实例中是否不支持模型遍历语法?如果支持,我做错了什么?
EDIT: If I uncomment readonly_fields, the error becomes:
编辑:如果我取消注释readonly_fields,错误变为:
Caught AttributeError while rendering: 'MyMainModelAdmin' object has no attribute '__name__'
1 个解决方案
#1
11
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).
根据Roseman上面的建议,您可以使用Inline管理模型以只读方式显示相关(一对一或多对一)数据。这是一个小例子,只是为了确保我们都在同一页面上。您可以在下面看到有三种方法可以实现您的目标(如果我正确理解了这一目标)。
models.py:
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:
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).
如您所见,根据contrib.admin的Django文档(从1.2开始),'readonly_fields'的处理方式与'list_display'相同。
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).
在上面的示例中,当您编辑公司时,您将看到其内联员工。每行在可编辑的文本框中都有一个员工姓名,在名称旁边,您将看到员工汽车的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:
参考您的原始问题,您希望将相关数据引用为“other__name”。这不行。在运行Django查询时,像other__name或car__rego这样的表达式在过滤器中只具有特殊含义作为关键字参数。例如,在获取拥有特定标识号的汽车的员工时:
Employee.objects.filter(car__rego='111')
Hope that helps.
希望有所帮助。
j
Ĵ
#1
11
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).
根据Roseman上面的建议,您可以使用Inline管理模型以只读方式显示相关(一对一或多对一)数据。这是一个小例子,只是为了确保我们都在同一页面上。您可以在下面看到有三种方法可以实现您的目标(如果我正确理解了这一目标)。
models.py:
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:
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).
如您所见,根据contrib.admin的Django文档(从1.2开始),'readonly_fields'的处理方式与'list_display'相同。
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).
在上面的示例中,当您编辑公司时,您将看到其内联员工。每行在可编辑的文本框中都有一个员工姓名,在名称旁边,您将看到员工汽车的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:
参考您的原始问题,您希望将相关数据引用为“other__name”。这不行。在运行Django查询时,像other__name或car__rego这样的表达式在过滤器中只具有特殊含义作为关键字参数。例如,在获取拥有特定标识号的汽车的员工时:
Employee.objects.filter(car__rego='111')
Hope that helps.
希望有所帮助。
j
Ĵ