РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
29 of 818 menu

Поле GeneratedField

Поле GeneratedField позволяет создавать в модели Django поля, значения которых вычисляются непосредственно на уровне базы данных. Данное поле принимает два обязательных параметра: выражение (expression), определяющее логику вычисления, и параметр output_field, задающий тип данных результата. Значения такого поля обновляются автоматически при изменении данных, от которых оно зависит, и не могут быть изменены вручную через ORM. Поле поддерживается PostgreSQL (начиная с версии 12), MariaDB (10.2+), MySQL (5.7+) и SQLite (3.31+).

Синтаксис

from django.db import models from django.db.models import F, Value from django.db.models.functions import Concat class ModelName(models.Model): field_name = models.GeneratedField( expression = Expression, output_field = models.FieldType(), db_persist = True / False )

Пример . Создание модели с GeneratedField

Создадим модель Product с вычисляемым полем полной стоимости с учетом налога:

from django.db import models from django.db.models import F from django.db.models.functions import Round class Product(models.Model): name = models.CharField(max_length=100) price = models.DecimalField(max_digits=10, decimal_places=2) tax_rate = models.DecimalField(max_digits=5, decimal_places=2, default=0.13) price_with_tax = models.GeneratedField( expression = Round(F('price') * (1 + F('tax_rate')), 2), output_field = models.DecimalField(max_digits=12, decimal_places=2), db_persist = True ) def __str__(self): return self.name

После создания модели поле price_with_tax будет автоматически вычисляться при добавлении или обновлении записей:

from myapp.models import Product product = Product.objects.create( name = 'Laptop', price = 1000.00, tax_rate = 0.13 ) print(product.price_with_tax)

Результат выполнения кода:

"1130.00"

Пример . С конкатенацией строк

Используем GeneratedField для создания полного имени пользователя из двух отдельных полей:

from django.db import models from django.db.models.functions import Concat from django.db.models import Value class User(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) full_name = models.GeneratedField( expression = Concat(F('first_name'), Value(' '), F('last_name')), output_field = models.CharField(max_length=101), db_persist = True ) def __str__(self): return self.full_name

Теперь при создании пользователя поле full_name заполняется автоматически:

from myapp.models import User user = User.objects.create( first_name = 'John', last_name = 'Doe' ) print(user.full_name)

Результат выполнения кода:

"John Doe"

Пример . С вычислением возраста

Создадим поле, которое будет вычислять возраст пользователя на основе даты рождения и текущей даты:

from django.db import models from django.db.models import F, Value from django.db.models.functions import ExtractYear, Cast, Now from django.db.models import IntegerField class Person(models.Model): name = models.CharField(max_length=100) birth_date = models.DateField() age = models.GeneratedField( expression = ExtractYear(Now()) - ExtractYear(F('birth_date')), output_field = models.IntegerField(), db_persist = False ) def __str__(self): return self.name

Обратите внимание, что параметр db_persist установлен в False, так как возраст зависит от текущей даты и должен вычисляться при каждом запросе, а не сохраняться в базе данных:

from myapp.models import Person from datetime import date person = Person.objects.create( name = 'Alice', birth_date = date(1990, 5, 15) ) print(f"{person.name} is {person.age} years old")

Результат выполнения кода:

"Alice is 36 years old"

Пример . С условным вычислением

Используем условное выражение для вычисления статуса заказа на основе суммы:

from django.db import models from django.db.models import F, Value, Case, When from django.db.models.functions import Round class Order(models.Model): customer_name = models.CharField(max_length=100) amount = models.DecimalField(max_digits=10, decimal_places=2) status = models.GeneratedField( expression = Case( When(amount__gte=1000.00, then=Value('Premium')), When(amount__gte=500.00, then=Value('Standard')), default=Value('Basic'), output_field=models.CharField(max_length=20) ), output_field = models.CharField(max_length=20), db_persist = True ) def __str__(self): return f"{self.customer_name} - {self.status}"

При создании заказов поле status будет автоматически определяться на основе суммы:

from myapp.models import Order Order.objects.create(customer_name = 'Bob', amount = 1200.00) Order.objects.create(customer_name = 'Charlie', amount = 750.00) Order.objects.create(customer_name = 'Dave', amount = 300.00) for order in Order.objects.all(): print(f"{order.customer_name}: {order.status}")

Результат выполнения кода:

"Bob: Premium" "Charlie: Standard" "Dave: Basic"

Смотрите также

  • поле CharField,
    которое используется для хранения строковых данных
  • поле DecimalField,
    которое используется для хранения чисел с плавающей точкой
  • поле DateField,
    которое используется для хранения дат
  • поле IntegerField,
    которое используется для хранения целых чисел
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить