保存后更新实例,在某些情况下通过有条件地引用实例来使用信号 [英] Update the instance after save, using signals by conditionally refference back to the instance in some cases
问题描述
我有以下抽象类:
class UserStamp(models.Model):
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True,
related_name='%(app_label)s_%(class)s_created_by', on_delete=models.CASCADE)
updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True,
related_name='%(app_label)s_%(class)s_updated_by', on_delete=models.CASCADE)
class Meta:
abstract = True
我有一个自定义用户,该用户继承自User。
I have a custom User that inherits from User.
class User(AbstractBaseUser,PermissionsMixin, UserStamp):
account = models.ForeignKey(Account, blank=True, null=True, related_name='owner',on_delete=models.CASCADE)
用户可以创建或更新自己或其他用户。
The User can create/update himself or by other user.
当用户自己创建/更新时,我什么都没有
When the user create/update himself I don't have anything for created_by, update_by.
可以使用Django Admin或在Django Admin外部创建用户。
The user can be created using Django Admin or outside Django Admin;
在Django Admin中,用户可以由工作人员创建,而Django之外的用户可以自行创建;
In Django Admin the user can be created by staff, outside Django is self created;
还有在终端中创建的超级用户;
Also there is superuser that is created in terminal;
关于更新,无论是Django Admin还是外部用户,都可以自我更新或由其他用户进行更新。
Regarding the update the user in both Django Admin and outside can be self updated or by another user.
我考虑使用post_save或自定义信号。问题是request.user在模型中不可用,但在View中不可用,并且在Admin和终端(超级用户)中控制View是一个瓶颈。
I thought on using post_save or a custom signal. The issue is that request.user is not available in the model, but in View, and controlling the View in Admin and also in terminal(superuser) is a bottleneck.
也许在保存通过实例后尝试进行查询,但是我不完全知道如何将所有这些信号/查询结合起来,检查超级用户。
Maybe trying to do a query after save passing the instance, but I don't exactly know how to combine all of them signal/query, check superuser.
推荐答案
创建自己的 自定义信号
。
from django.dispatch import Signal
# you can pass any number of arguments as per your requirement.
manage_user = Signal(providing_args=["user", "is_updated"])
def user_handler(sender, **kwargs):
# `user` who created/updated object i.e `request.user`
user = kwargs['user']
# `is_updated` will be `False` if user object created.
is_updated = kwargs['is_updated']
# `sender` is the user object which is created/updated.
...
# do your stuff
manage_user.connect(user_handler)
models.py
覆盖 save()
from .signals import manage_user
class User(...):
...
# call this save method like obj.save(created_by=request.user)
def save(self, created_by, *args, **kwargs):
super().save(*args, **kwargs)
# is_updated will be True if user object is updated
manage_user.send(sender=self, user=created_by, is_updated=True if self.id else False)
发送
manage_user
在用户模型更改时发出信号,就像post_save
信号一样,
,但是现在您可以控制参数了。
send
manage_user
signal when user model changed, just likepost_save
signal, but now you have control over parameters.
更新
如果您使用django admin创建用户,则可以覆盖 save_model ,您在那里有请求对象。
UPDATE
If you are using django admin to create user you can overide save_model, you have request object there.
from django.contrib import admin
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
super(UserAdmin, self).save_model(request, obj, form, change)
manage_user.send(sender=self, user=request.user, is_updated=True if self.id else False)
这篇关于保存后更新实例,在某些情况下通过有条件地引用实例来使用信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!