无法在Django UpdateView form_valid或signal中动态保存user.is_active



我有两个模型,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)

最新更新