Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 重写Django ModelForm中的save()方法以创建或更新_Python_Django - Fatal编程技术网

Python 重写Django ModelForm中的save()方法以创建或更新

Python 重写Django ModelForm中的save()方法以创建或更新,python,django,Python,Django,简介: 我希望重写自定义模型表单中的save()方法,以便在模型中创建新行,或者更新某些数据(如果存在)。我已经找到了一些解决方案,但是它是在视图函数中实现的,就像这个链接一样,但是我想在表单save()方法中实现它 我的型号: 我有默认的auth.User模型和我的Author模型,如下所示,我还有另一个名为UserAuthor的模型,用于它们之间的许多关系,因为在我的情况下,添加其他字段如“is_follow”和“review”是必需的 class Author(models.Model):

简介:

我希望重写自定义模型表单中的save()方法,以便在模型中创建新行,或者更新某些数据(如果存在)。我已经找到了一些解决方案,但是它是在视图函数中实现的,就像这个链接一样,但是我想在表单save()方法中实现它

我的型号:

我有默认的auth.User模型和我的Author模型,如下所示,我还有另一个名为UserAuthor的模型,用于它们之间的许多关系,因为在我的情况下,添加其他字段如“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})
我的观点:

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在评论和回答之间,我想我们已经讨论并达成了一个适当的解决方案。如果您愿意,您可以在满意的情况下关闭问题(通过选中“接受答案”按钮)。或者我们可以保持现状。