在使用 Django 的 Model.save() 之前执行操作的最佳方法是什么?



我在我的项目中使用Django-Rest-Framework(ViewSet方法)与React应用程序交互。所以,我没有使用Django admin或Django表单。

我的项目结构是:

  1. 视图
  2. 序列化程序

我需要做的是在模型方法调用之前执行操作:

  1. 在"模型"字段上插入 request.user。
  2. 在 Model.save() 之后启动打印机进程
  3. .....

我已经在Django.docs上阅读了很多关于django-way to do的信息,在那里,这些东西似乎显示为类似Django-Admin的项目,这不是我的情况。

另一方面,通过阅读 Stack 在其他主题中的答案,这样做的方法似乎是:"它会起作用,但是,这不是正确的方法"。

  1. 根据 Django 的文档,最好的方法是使用一个名为 admin.py 的新文件,我将在其中注册绑定到可以支持保存、删除等的模型的操作,但是,目前尚不清楚这种方法是这样做还是仅用于提供 Django-Admin 的方式来执行操作。
# app/models.py
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
user = models.ForeignKey(User)
content = models.TextField()
class Comment(models.Model):
post = models.ForeignKey(Post)
user = models.ForeignKey(User)
content = models.TextField()
# app/admin.py
from app.models import Post, Comment
from django.contrib import admin
class CommentInline(admin.TabularInline):
model = Comment
fields = ('content',)
class PostAdmin(admin.ModelAdmin):
fields= ('content',)
inlines = [CommentInline]
def save_model(self, request, obj, form, change): 
obj.user = request.user
obj.save()
def save_formset(self, request, form, formset, change): 
if formset.model == Comment:
instances = formset.save(commit=False)
for instance in instances:
instance.user = request.user
instance.save()
else:
formset.save()
admin.site.register(Post, PostAdmin)

根据我听到的答案,最好的方法是在模型上使用类似的东西:

class MyModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
return super(MyModelForm, self).__init__(*args, **kwargs)
def save(self, *args, **kwargs):
kwargs['commit']=False
obj = super(MyModelForm, self).save(*args, **kwargs)
if self.request:
obj.user = self.request.user
obj.save()
return obj

我想知道的是: 执行该操作的最佳方法是什么,在哪些文件上,最佳结构是什么。

要在模型字段上插入request.user,您可以在视图类上使用perform_create()方法。 有关更多信息,请访问 https://www.django-rest-framework.org/tutorial/4-authentication-and-permissions/#associating-snippets-with-users 这正是您想要的!

我不确定启动打印机进程是什么意思,但您通常可以在保存模型 instace 后重写模型类save()方法来执行进程。 https://www.django-rest-framework.org/api-guide/serializers/#overriding-save-directly

  • 我发现在模型上插入 request.user 作为"created_by"字段的最佳方法是在模型序列化程序上插入一个带有默认数据的隐藏字段,如下所示:
my_field = serializers.HiddenField(default=serializers.CurrentUserDefault())

CurrentUserDefault()是一个将用户请求返回到序列化程序的函数。

https://www.django-rest-framework.org/api-guide/validators/#advanced-field-defaults

  • 对于在保存/删除之后/之前执行的操作,我选择使用 Django 信号,它用作操作的调度程序,有点像 react 的 redux。

https://docs.djangoproject.com/en/2.2/topics/signals/

谢谢大家的有用答案。

最新更新