DEV Community

Odipo Otieno
Odipo Otieno

Posted on

@property decorator in django models

In Django models, the @property decorator is used to define methods that behave like attributes, allowing you to create custom model properties. These properties can encapsulate logic and calculations, making them available as read-only attributes on model instances. Here’s how to use the @property decorator in a Django model:

Example

Let's say you have a Book model with title and author_first_name, author_last_name fields, and you want to create a property called author_full_name that combines the author's first and last names.

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100)
    author_first_name = models.CharField(max_length=50)
    author_last_name = models.CharField(max_length=50)

    @property
    def author_full_name(self):
        return f"{self.author_first_name} {self.author_last_name}"

# Usage
book = Book.objects.get(pk=1)
print(book.author_full_name)  # Outputs: Firstname Lastname
Enter fullscreen mode Exit fullscreen mode

Key Points

  1. Read-Only: Properties created using @property are read-only. You cannot set them directly. If you need a writable property, you can define custom setter methods using the @property.setter decorator.

  2. Calculations and Logic: You can perform calculations or other logic inside the property method to dynamically generate the attribute value.

  3. Usage in Querysets: Since the property is calculated in Python and not stored in the database, you cannot directly use it in database queries. If you need to filter or sort based on such properties, you might need to use annotations or other query constructs.

Example with Setter

If you want to allow setting the author_full_name as well, you can define a setter for the property:

class Book(models.Model):
    title = models.CharField(max_length=100)
    author_first_name = models.CharField(max_length=50)
    author_last_name = models.CharField(max_length=50)

    @property
    def author_full_name(self):
        return f"{self.author_first_name} {self.author_last_name}"

    @author_full_name.setter
    def author_full_name(self, full_name):
        first_name, last_name = full_name.split(' ', 1)
        self.author_first_name = first_name
        self.author_last_name = last_name

# Usage
book = Book.objects.get(pk=1)
book.author_full_name = "NewFirstname NewLastname"
book.save()
print(book.author_first_name)  # Outputs: NewFirstname
print(book.author_last_name)   # Outputs: NewLastname
Enter fullscreen mode Exit fullscreen mode

Limitations

  • Database Queries: Properties cannot be used in queryset filters or orderings. For example, you cannot do Book.objects.filter(author_full_name="John Doe").
  • Performance: Since properties are calculated in Python, they might introduce performance overhead if used extensively on large datasets.

Using properties in Django models helps keep your code clean and encapsulate logic within the model, promoting the principles of object-oriented programming.

Top comments (0)