Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
573 views
in Technique[技术] by (71.8m points)

python - How to add a calculated field to a Django model

I have a simple Employee model that includes firstname, lastname and middlename fields.

On the admin side and likely elsewhere, I would like to display that as:

lastname, firstname middlename

To me the logical place to do this is in the model by creating a calculated field as such:

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)

Ultimately what I think I need is to get the value of the name fields as strings. The error I am getting is value_to_string() takes exactly 2 arguments (1 given). Value to string wants self, obj. I am not sure what obj means.

There must be an easy way to do this, I am sure I am not the first to want to do this.

Edit: Below is my code modified to Daniel's answer. The error I get is:

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)
Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

That's not something you do as a field. Even if that syntax worked, it would only give the value when the class was defined, not at the time you access it. You should do this as a method, and you can use the @property decorator to make it look like a normal attribute.

@property
def name(self):
    return ''.join(
        [self.lastname,' ,', self.firstname, ' ', self.middlename])

self.lastname etc appear as just their values, so no need to call any other method to convert them.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...