我有一个代表书页的模型。
class BookPage(models.Model):
def getMaximumPageNumber():
page_numbers = (i.page_number for i in BookPage.objects.all())
return max(page_numbers)+1
page_number = models.IntegerField(default=getMaximumPageNumber, validators=[MinValueValidator(1)])
book = models.ForeignKey('Book', on_delete=models.CASCADE)
//other stuff
我希望Django在创建时自动分配页码,因此我制作了getMaximumPageNumber()
。如果我只有一本书,那就行得很好。但现在我想从这个函数中引用book
,所以它就像page_numbers = (i.page_number for i in BookPage.objects.filter(book=self.book)
。但问题是我似乎无法在此函数中使用self
,因为如果我将其指定为def getMaximumPageNumber(self):
,那么当我尝试访问时它会显示TypeError: getMaximumPageNumber() missing 1 required positional argument: 'self'
在管理员中添加页面屏幕。因此我无法指定我想要找到最大页面的书,这就是我真正需要在这里完成的。
有没有办法从默认分配函数引用新创建的模型实例的另一个字段?我最初的解决方案是覆盖此模型的save()
,但它打破了我已经写过的其他一些事情,因此使用动态"默认"如果在我的情况下可能会更好。
答案 0 :(得分:1)
首先,应该更新最大页面计算方法。通过重写Django模型save()方法可以实现这样的要求:
from django.db.models import Max
class BookPage(models.Model):
page_number = models.IntegerField(default=getMaximumPageNumber, validators=[MinValueValidator(1)])
book = models.ForeignKey('Book', on_delete=models.CASCADE)
def save(self, *args, **kwargs):
queryset = BookPage.objects.filter(book=self.book).aggregate(Max('page_number'))
max_page = queryset['page_number__max']
self.page_number = max_page +1
super(BookPage, self).save(*args, **kwargs)
答案 1 :(得分:0)
在管理模型中覆盖save_model
更容易。并且它不会导致覆盖模型save()
def save_model(self, request, obj, form, change):
max_page = BookPage.objects.filter(book=obj.book).aggregate(Max('page_number'))['page_number__max']
obj.page_number = max_page + 1
obj.save()
向Prakhar Trivedi致敬reminder about aggregations。