Django - перед созданием модели

У меня есть модель:

book(book_id, release_year, book_number_by_release_year)

Поле book_number_by_release_year должно автоматически генерироваться и увеличиваться на 1 в поле release_year для новых экземпляров модели.

Какой лучший способ сделать это в Django? Спасибо за помощь

из документации django вы можете создать пользовательские команды django-admin и если ваша операционная система основана на unix, эта команда будет автоматически вызываться, когда ее дата будет соответствовать заданной вами, смотрите пример в docs выше

from django.core.management.base import BaseCommand, CommandError
from polls.models import Question as Poll

class Command(BaseCommand):
    help = 'Closes the specified poll for voting'

    def add_arguments(self, parser):
        parser.add_argument('poll_ids', nargs='+', type=int)

    def handle(self, *args, **options):
        for poll_id in options['poll_ids']:
            try:
                poll = Poll.objects.get(pk=poll_id)
            except Poll.DoesNotExist:
                raise CommandError('Poll "%s" does not exist' % poll_id)
            # you can type your logic here 
            poll.opened = False
            poll.save()

            self.stdout.write(self.style.SUCCESS('Successfully closed poll "%s"' % poll_id))

это автоматически закроет опросы, созданные пользователем
. для вашего случая

def handle(self, *args, **options):
        .
        .

            # you can type your logic here 
            if (datetime.date.today() - self.release_year) == 0:
            self.book_number_by_release_year +=1
            self.save() 

подумайте о добавлении ваших попыток и models.py для более подробного ответа и для хорошего вопроса проверьте этот вопрос для более подробной информации

Вы можете использовать сигнал pre_save или переопределить метод save. Я предпочитаю первый вариант, так как мы не изменяем методы, определенные django. Вот примерная реализация использования pre_save сигнала:

from django.db.models.signals import pre_save
from django.db.models import Max
from django.db import models

class Book(models.Model):
    book_id = models.IntegerField()
    release_year = models.IntegerField()
    book_number_by_release_year = models.IntegerField()


@receiver(pre_save, sender=Book)
def populate_book_number_by_release_year(sender, instance, *args, **kwargs):
    # fetch the last book_id given
    args = Book.objects.filter(release_year=instance.release_year)
    max_value = args.aggregate(Max('book_number_by_release_year'))
    
    if max_value == None:
        instance.book_number_by_release_year=0
    else:
        instance.book_number_by_release_year=max_value['book_number_by_release_year']

PS: Обратите внимание, что существует возможность возникновения состояния гонки, как и в любой другой autoincrement функции.

Документация: https://docs.djangoproject.com/en/4.1/ref/signals/

Мы можем попробовать использовать AutoField для вышеупомянутого случая использования. Вместо того чтобы полагаться на сигнал pre_save, мы можем внести изменения в определение модели следующим образом:

class Book(models.Model):
    book_id = models.IntegerField()
    release_year = models.IntegerField()
    book_number_by_release_year = models.AutoField(primary_key=False)

Ссылка на официальную документацию: https://docs.djangoproject.com/en/4.0/ref/models/fields/#autofield

Вернуться на верх