覆盖Django ModelForm中的save()方法以创建或更新

时间:2017-08-28 16:21:16

标签: python django

简介:

我想覆盖自定义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()方法本身如何?

1 个答案:

答案 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

我希望这会以某种方式引导你。 感谢。