Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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) 
like image 364
cstrutton Avatar asked Jul 16 '13 16:07

cstrutton


People also ask

How do I add a calculated field in Django?

get_queryset() method by appending your calculated field. The calculated field is created using . annotate() . Finally, you set the objects Manager in your Model to your new Manager .

How do I add a field to an existing model in Django?

To answer your question, with the new migration introduced in Django 1.7, in order to add a new field to a model you can simply add that field to your model and initialize migrations with ./manage.py makemigrations and then run ./manage.py migrate and the new field will be added to your DB.

How does Django calculate?

budget: calc_budget = self. budget - add_price return "You are under budget with ${} left over". format(calc_budget) else: return "Cannot Compute, please add in a budget and/or product prices."

Is there a list field for Django models?

Mine is simpler to implement, and you can pass a list, dict, or anything that can be converted into json. In Django 1.10 and above, there's a new ArrayField field you can use.


1 Answers

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.

like image 171
Daniel Roseman Avatar answered Sep 27 '22 20:09

Daniel Roseman