简介:
我想覆盖自定义ModelForm中的save()方法,以在模型中创建新行或更新某些数据(如果存在)。我已经找到了一些解决方案,但它在视图函数中实现,如链接Django form INSERTs when I want it to UPDATE,但我想以save()方法的形式实现它。
我的模特:
我有默认的 auth.User 模型和我的作者模型,如下所示,我还有另一个名为 UserAuthor 的模型,用于ManyToMany它们之间的关系,因为在我的情况下,添加“is_follow”和“review”
等其他字段是强制性的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})
在这种情况下,它会在数据库中为每个save()调用创建一个新行。我不知道在保存之前如何检查save方法,只是在请求者用户与作者有前一行的情况下更新,我尝试了很多东西但是我失败了。我知道我可以使用:
user_author = UserAuthor.objects.filter(user=user, author=author)
如果返回结果则更新,但save()方法本身如何?
答案 0 :(得分:3)
使用django queryset get_or_create()
方法。
来自文档:此方法用于查找具有给定kwargs的对象(如果您的模型具有所有字段的默认值,则可能为空),必要时创建一个。
详细了解here in the docs。
现在,在您的观点中:
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})
现在,在你的ModelForm中:
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
我希望这会以某种方式引导你。 感谢。