Django: def save() in models.py

Tags: , , ,



I’m trying to add the save-function inside my models.py, but it seems I’m doing something wrong. The user has to type the first- and last-name. Without him or her entering any more data, another field inside my models.py should be filled with a combination from these fields.

models.py:

class Coworker(models.Model):
    first_name = models.CharField(max_length=50, null=False, blank=False)
    last_name = models.CharField(max_length=50, null=False, blank=False)
    full_name = models.CharField(max_length=100, null=False, blank=False)

    def save(self, *args, **kwargs):
        self.full_name = self.first_name + " " + self.last_name
        super().save(*args, **kwargs)

Is this even possible? Thanks for all your help.

Have a nice weekend!

Answer

Please don’t. This is redundant data. It turns out that keeping data in sync, even on the same database is more challening than it might look at first sight. Django has furthermore several functions like .update(…) [Django-doc] to update records in the table, but circumventing the .save() call.

You can for example use a property that will calculate the full_name at runtime at the Django/Python level:

class Coworker(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)

    @property
    def full_name(self):
        return f'{self.first_name} {self.last_name}'

If you want to be able to filter on the full_name for example, you can make an annotation, in this case with Concat [Django-doc]:

from django.db.models import CharField, Value
from django.db.models.functions import Concat

Coworker.objects.annotate(
    full_name=Concat(
        'first_name', Value(' '), 'last_name',
         output_field=CharField()
    )
).filter(full_name__icontains='some query')


Source: stackoverflow