У меня есть сигнал в моем приложении django, где я хотел бы проверить, было ли обновлено определенное поле в моей модели, чтобы я мог затем продолжить и что-то сделать.
Моя модель выглядит следующим образом ...
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.PositiveIntegerField()
tax_rate = models.PositiveIntegerField()
display_price = models.PositiveInteger()
inputed_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL)
updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL)
Мой сигнал выглядит следующим образом ...
@receiver(post_save, sender=Product)
def update_model(sender, **kwargs):
instance = kwargs['instance']
if 'tax_rate' in kwargs['update_fields']:
# do something
Это возвращает ошибку None
не являетсяитерация.Я прочитал документацию по сигналу django относительно update_fields
и там написано The set of fields to update as passed to Model.save(), or None if update_fields wasn’t passed to save().
Я должен упомянуть, что здесь я работаю с администратором django, поэтому я надеялся, что я смогу создать экземпляр своегоМодель продукта в django admin, а затем, если значение tax_rate или цена были обновлены, я могу проверить их и соответственно обновить list_price
.Однако kwargs['update_fields']
всегда возвращает None.Что я делаю не так?Или есть какой-то другой способ добиться этого результата внутри администратора django?
Обновлен раздел
Теперь, скажем, я ввел поле под названием inputed_by
в моей модели продукта., это указывает на пользовательскую модель, и я хочу, чтобы это поле заполнялось при первом сохранении модели.Затем другое поле updated_by
, в котором хранится пользователь, который последний раз обновлял модель.В то же время я хочу проверить, был ли обновлен tax_rate
или price
.
Внутри администратора моей модели у меня есть следующий метод ...
def save_model(self, request, obj, form, change):
update_fields = []
if not obj.pk:
obj.inputed_by = request.user
elif change:
obj.updated_by = request.user
if form.initial['tax_rate'] != form.cleaned_data['tax_rate']:
update_fields.append('tax_rate')
if form.initial['price'] != form.cleaned_data['price']:
update_fields.append('price')
obj.save(update_fields=update_fields)
super().save_model(request, obj, form, change)
Мой сигнал теперь выглядит следующим образом ...
@receiver(post_save, sender=Product, dispatch_uid="update_display_price")
def update_display_price(sender, **kwargs):
created = kwargs['created']
instance = kwargs['instance']
updated = kwargs['update_fields']
checklist = ['tax_rate', 'price']
# Prints out the frozenset containing the updated fields and then below that `The update_fields is None`
print(f'The update_fields is {updated}')
if created:
instance.display_price = instance.price+instance.tax_rate
instance.save()
elif set(checklist).issubset(updated):
instance.display_price = instance.price+instance.tax_rate
instance.save()
Я получаю ошибку 'NoneType' object is not iterable
Ошибка, кажется, исходит от линии set(checklist).issubset(updated)
.Я попытался запустить эту строку специально внутри оболочки Python, и она дает желаемые результаты.Что не так в этот раз?