Python 重写Django ModelForm中的save()方法以创建或更新
简介: 我希望重写自定义模型表单中的save()方法,以便在模型中创建新行,或者更新某些数据(如果存在)。我已经找到了一些解决方案,但是它是在视图函数中实现的,就像这个链接一样,但是我想在表单save()方法中实现它 我的型号: 我有默认的auth.User模型和我的Author模型,如下所示,我还有另一个名为UserAuthor的模型,用于它们之间的许多关系,因为在我的情况下,添加其他字段如“is_follow”和“review”是必需的Python 重写Django ModelForm中的save()方法以创建或更新,python,django,Python,Django,简介: 我希望重写自定义模型表单中的save()方法,以便在模型中创建新行,或者更新某些数据(如果存在)。我已经找到了一些解决方案,但是它是在视图函数中实现的,就像这个链接一样,但是我想在表单save()方法中实现它 我的型号: 我有默认的auth.User模型和我的Author模型,如下所示,我还有另一个名为UserAuthor的模型,用于它们之间的许多关系,因为在我的情况下,添加其他字段如“is_follow”和“review”是必需的 class Author(models.Model):
class Author(models.Model):
name = models.CharField(max_length=50)
class UserAuthor(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
is_follow = models.BooleanField(default=0)
review = models.TextField(max_length=500, blank=True, null=True)
我的表格:
class ReviewFollowAuthorForm(forms.ModelForm):
class Meta:
model = UserAuthor
fields = ("is_follow", "review")
def save(self, commit=True, user=None, author=None):
user_author = super(ReviewFollowAuthorForm, self).save(commit=False)
user_author.user = user
user_author.author = author
if commit:
user_author.save()
return user_author
class ReviewFollowAuthor(View):
def post(self, request, **kwargs):
user = request.user
author = get_object_or_404(Author, id=kwargs['pk'])
f = ReviewFollowAuthorForm(request.POST)
if(f.is_valid()):
f.save(user=user,userx=userx)
return JsonResponse({'success':1})
else:
return JsonResponse({'success':0})
我的观点:
class ReviewFollowAuthorForm(forms.ModelForm):
class Meta:
model = UserAuthor
fields = ("is_follow", "review")
def save(self, commit=True, user=None, author=None):
user_author = super(ReviewFollowAuthorForm, self).save(commit=False)
user_author.user = user
user_author.author = author
if commit:
user_author.save()
return user_author
class ReviewFollowAuthor(View):
def post(self, request, **kwargs):
user = request.user
author = get_object_or_404(Author, id=kwargs['pk'])
f = ReviewFollowAuthorForm(request.POST)
if(f.is_valid()):
f.save(user=user,userx=userx)
return JsonResponse({'success':1})
else:
return JsonResponse({'success':0})
在这种情况下,它会为每个save()调用在数据库中创建一个新行。我不知道如何在保存之前签入save方法,只是在请求者用户和作者有前一行的情况下进行更新,我尝试了很多方法,但都失败了。我知道我可以使用:
user_author = UserAuthor.objects.filter(user=user, author=author)
并在返回结果时进行更新,但如何在save()方法本身中进行更新?使用django queryset
获取或创建()方法
来自文档:此方法用于查找具有给定KWARG的对象(如果模型的所有字段都有默认值,则可能为空),必要时创建一个
阅读更多关于它的信息
现在,在您的视图中:
class ReviewFollowAuthor(View):
def post(self, request, **kwargs):
user = request.user
author = get_object_or_404(Author, id=kwargs['pk'])
#MAKE certain that user and author always have an instance within them.
#send the user, author to the form.
f = ReviewFollowAuthorForm(request.POST , user = user , author = author)
if(f.is_valid()):
f.save(user=user,userx=userx)
return JsonResponse({'success':1})
else:
return JsonResponse({'success':0})
现在,在您的模型表单中:
class ReviewFollowAuthorForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
#override __init__ to make your "self" object have the instances sent by the your views.(author and user)
self.user = kwargs.pop('user' , None)
self.author = kwargs.pop('author' , None)
#Now your model-form instance has the user and the author attribute within itself.
super(ReviewFollowAuthorForm, self).__init__(*args, **kwargs)
class Meta:
model = UserAuthor
fields = ("is_follow", "review")
def save(self, commit=True):
user_author, created = UserAuthor.objects.update_or_create( user=self.user, author=self.author, defaults={'is_follow': self.cleaned_data.get('is_follow'), 'review': self.cleaned_data.get('review')} )
#rest of your logic
return user_author
我希望这能在某种程度上指导你。
谢谢。对不起,我对你的回答感到困惑。你说我可以使用get\u或\u create()
但是在哪里?此外,在“except”情况下,将使用POST请求正文中的额外字段创建新记录。很好,但是在“try”案例中,如何更新user_author的字段而不从请求主体中单独获取字段?@yassermohsen我已经更新了我的答案,并尝试更详细一点。请检查一下。它正在工作,谢谢。但是我更新了您的代码,并使用了update\u或\u create()
方法和defaults
属性,以便更容易地更新字段<代码>定义保存(self,commit=True):user\u author,created=UserAuthor.objects.update\u或\u create(user=self.user,author=self.author,默认值={'is\u follow':self.cleaned\u data.get('is\u follow'),'review':self.cleaned\u data.get('review'))return userxuser
请在您的答案中更新它,以使其他人清楚,并从save()方法中删除用户和作者arguments@yassermohsen谢谢。事实上,连我都不知道有这样的方法存在。我总是通过get\u或\u create()
获取对象,然后对其进行更新<代码>更新或创建()显然是这个用例更好的方法。谢谢。@yassermohsen在评论和回答之间,我想我们已经讨论并达成了一个适当的解决方案。如果您愿意,您可以在满意的情况下关闭问题(通过选中“接受答案”按钮)。或者我们可以保持现状。