我有两个模型,User
(扩展Abstract User
并继承is_active
字段(和Supervision
连接到具有通用外键的用户。当我们保存Supervisory的实例时,代码必须检查Supervisory实例上的suspended
字段,并将user.is_active
更新为相反的字段。我无法保存保存用户实例,因为它会恢复为True并保存两次。这是我来自form_valid()
:的代码
suspension, created = Suspension.objects.get_or_create(
content_type = ContentType.objects.get(app_label="myapp", model="suspension"),
object_id = self.kwargs['pk'],
)
suspension.reason = form.cleaned_data['reason']
suspension.suspended = form.cleaned_data['suspended']
suspension.save()
user = suspension.content_object
user.is_active = False if suspension.suspended else True
user.save()
return super().form_valid(form)
这是我的信号:
@receiver(post_save, sender=Suspension, weak=False, dispatch_uid=uuid.uuid4())
def suspend_unsuspend_user(sender, instance, **kwargs):
from userprofile.models import User
if isinstance(instance.content_object, User):
user = instance.content_object
user.is_active = instance.suspended
user.save()
UPDATE:覆盖Suspension
模型上的save((以更新用户实例
def save(self, *args, **kwargs):
from userprofile.models import User
if isinstance(self.content_object, User):
try:
user = self.content_object
user.is_active = False if self.suspended else True
user.save()
except:
raise RuntimeError('Unable to find user')
return super().save(*args, **kwargs)
没用
在分别实现它们的同时,我将用户实例保存两次,每次user.is_active都恢复为True并保存(即,用户实例上的postrongave信号将其打印两次,最终始终为True(。我已经检查了我的代码,我在其他任何地方都不接触user.is_active。此外,我还可以从admin或shell更改is_active。怎么了?
问题出现在form_valid()
方法中。该问题是由代码在super().form_valid(form)
之前单独保存悬架引起的。代码通过将其更改为:
def form_valid(self, form):
suspension, created = Suspension.objects.get_or_create(
content_type = ContentType.objects.get(app_label="myapp", model="suspension"),
object_id = self.kwargs['pk'],
)
suspension.reason = form.cleaned_data['reason']
suspension.suspended = form.cleaned_data['suspended']
form.instance = suspension # <-- here's the solution: we overwrite the form.instance and let django do its job.
user = suspension.content_object
user.is_active = False if suspension.suspended else True
user.save()
return super().form_valid(form)