我有个模特:
book(book_id, release_year, book_number_by_release_year)
对于新的模型实例,必须在book_number_by_release_year
字段中自动生成字段release_year
并将其递增1。
在Django中做这件事的最好方法是什么?谢谢你的帮助
发布于 2022-09-05 08:30:55
在django文档中,您可以使用创建自定义django-admin命令,如果您的操作系统是基于unix的,那么这个命令将在您设置的日期时自动调用,在上面的文档中查看表单示例
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以获得更详细的答案,要获得更好的问题,请查看这个问题获得更多详细信息
发布于 2022-09-05 08:37:19
可以使用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
函数一样,存在竞争条件的可能性。
发布于 2022-09-06 00:46:20
我们可以尝试在上面的用例中使用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
https://stackoverflow.com/questions/73612067
复制