cst*_*ton 46 python django-models django-admin
我有一个简单的Employee
模型,其中包括firstname
, lastname
和middlename
领域.
在管理员方面,可能在其他地方,我想将其显示为:
lastname, firstname middlename
Run Code Online (Sandbox Code Playgroud)
对我来说,这样做的合理位置是在模型中通过创建一个计算字段:
from django.db import models
from django.contrib import admin
class Employee(models.Model):
lastname = models.CharField("Last", max_length=64)
firstname = models.CharField("First", max_length=64)
middlename = models.CharField("Middle", max_length=64)
clocknumber = models.CharField(max_length=16)
name = ''.join(
[lastname.value_to_string(),
',',
firstname.value_to_string(),
' ',
middlename.value_to_string()])
class Meta:
ordering = ['lastname','firstname', 'middlename']
class EmployeeAdmin(admin.ModelAdmin):
list_display = ('clocknumber','name')
fieldsets = [("Name", {"fields":(("lastname", "firstname", "middlename"), "clocknumber")}),
]
admin.site.register(Employee, EmployeeAdmin)
Run Code Online (Sandbox Code Playgroud)
最终我认为我需要的是将名称字段的值作为字符串.我得到的错误是value_to_string() takes exactly 2 arguments (1 given)
.字符串想要的值self, obj
.我不确定是什么obj
意思.
必须有一个简单的方法来做到这一点,我相信我不是第一个想要这样做的人.
编辑:这是我的代码修改为丹尼尔的答案.我得到的错误是:
django.core.exceptions.ImproperlyConfigured:
EmployeeAdmin.list_display[1], 'name' is not a callable or an
attribute of 'EmployeeAdmin' of found in the model 'Employee'.
from django.db import models
from django.contrib import admin
class Employee(models.Model):
lastname = models.CharField("Last", max_length=64)
firstname = models.CharField("First", max_length=64)
middlename = models.CharField("Middle", max_length=64)
clocknumber = models.CharField(max_length=16)
@property
def name(self):
return ''.join(
[self.lastname,' ,', self.firstname, ' ', self.middlename])
class Meta:
ordering = ['lastname','firstname', 'middlename']
class EmployeeAdmin(admin.ModelAdmin):
list_display = ('clocknumber','name')
fieldsets = [("Name", {"fields":(("lastname", "firstname", "middlename"), "clocknumber")}),
]
admin.site.register(Employee, EmployeeAdmin)
Run Code Online (Sandbox Code Playgroud)
Dan*_*man 68
这不是你作为一个领域所做的事情.即使该语法有效,它也只会在定义类时给出值,而不是在您访问它时.您应该将此作为一种方法,并且您可以使用@property
装饰器使其看起来像普通属性.
@property
def name(self):
return ''.join(
[self.lastname,' ,', self.firstname, ' ', self.middlename])
Run Code Online (Sandbox Code Playgroud)
self.lastname
etc只显示为它们的值,因此无需调用任何其他方法来转换它们.
cst*_*ton 39
好的......丹尼尔罗斯曼的回答似乎应该有效.总是这样,您在发布问题后找到了您要查找的内容.
从django 1.5文档我发现这个开箱即用的例子.感谢大家的帮助.
这是有效的代码:
from django.db import models
from django.contrib import admin
class Employee(models.Model):
lastname = models.CharField("Last", max_length=64)
firstname = models.CharField("First", max_length=64)
middlename = models.CharField("Middle", max_length=64)
clocknumber = models.CharField(max_length=16)
def _get_full_name(self):
"Returns the person's full name."
return '%s, %s %s' % (self.lastname, self.firstname, self.middlename)
full_name = property(_get_full_name)
class Meta:
ordering = ['lastname','firstname', 'middlename']
class EmployeeAdmin(admin.ModelAdmin):
list_display = ('clocknumber','full_name')
fieldsets = [("Name", {"fields":(("lastname", "firstname", "middlename"), "clocknumber")}),
]
admin.site.register(Employee, EmployeeAdmin)
Run Code Online (Sandbox Code Playgroud)
Ale*_*lia 24
丹尼尔·罗斯曼的解决方案,使计算字段的属性Model
,但它并不能使它通过QuerySet的方法访问(例如.all()
,.values()
).这是因为QuerySet方法直接调用数据库,绕过了django Model
.
由于查询集直接访问数据库,解决的办法是重写Manager
的.get_queryset()
通过附加的计算字段的方法.使用创建计算字段.annotate()
.最后,您将objects
管理器设置为Model
新的Manager
.
以下是一些证明这一点的代码:
models.py
from django.db.models.functions import Value, Concat
from django.db import Model
class InvoiceManager(models.Manager):
"""QuerySet manager for Invoice class to add non-database fields.
A @property in the model cannot be used because QuerySets (eg. return
value from .all()) are directly tied to the database Fields -
this does not include @property attributes."""
def get_queryset(self):
"""Overrides the models.Manager method"""
qs = super(InvoiceManager, self).get_queryset().annotate(link=Concat(Value("<a href='#'>"), 'id', Value('</a>')))
return qs
class Invoice(models.Model):
# fields
# Overridden objects manager
objects = InvoiceManager()
Run Code Online (Sandbox Code Playgroud)
现在,您将能够调用.values()
或.all()
访问在... link
中声明的新计算的属性Manager
.
这本来也一直可以使用其他的功能的.annotate()
,如F()
.
我相信该属性仍然无法使用object._meta.get_fields()
.我相信你可以在这里添加它,但我还没有探究过 - 任何编辑/评论都会有所帮助.
小智 8
我最近在一个图书馆工作,可以很轻松地解决您遇到的问题。
https://github.com/brechin/django-computed-property
安装它,添加到INSTALLED_APPS,然后
class Employee(models.Model):
...
name = computed_property.ComputedCharField(max_length=3 * 64, compute_from='full_name')
@property
def full_name(self):
return '{LAST}, {FIRST} {MIDDLE}'.format(LAST=self.lastname, FIRST=self.firstname, MIDDLE=self.middlename')
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
47100 次 |
最近记录: |