cst*_*ton 46 python django-models django-admin
我有一个简单的Employee模型,其中包括firstname,   lastname和middlename领域.
在管理员方面,可能在其他地方,我想将其显示为:
lastname, firstname middlename
对我来说,这样做的合理位置是在模型中通过创建一个计算字段:
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)
最终我认为我需要的是将名称字段的值作为字符串.我得到的错误是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)
Dan*_*man 68
这不是你作为一个领域所做的事情.即使该语法有效,它也只会在定义类时给出值,而不是在您访问它时.您应该将此作为一种方法,并且您可以使用@property装饰器使其看起来像普通属性.
@property
def name(self):
    return ''.join(
        [self.lastname,' ,', self.firstname, ' ', self.middlename])
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)
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()
现在,您将能够调用.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')
| 归档时间: | 
 | 
| 查看次数: | 47100 次 | 
| 最近记录: |