Django &引用;无法在没有主键的save()中强制更新";-提交编辑/更新表单时

Django &引用;无法在没有主键的save()中强制更新";-提交编辑/更新表单时,django,Django,我有一个编辑表单,我只想更新一篇文章的“标题”、“内容”和“类别”。为此,我在保存表单时包含了update\u字段。然而,这有一个小问题。Django在提交表单时引发ValueError(特别是“无法在没有主键的情况下强制保存()中更新”)。它为什么要这样做,我怎样才能解决这个问题 邮寄表格: class PostForm(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*

我有一个编辑表单,我只想更新一篇文章的“标题”、“内容”和“类别”。为此,我在保存表单时包含了
update\u字段
。然而,这有一个小问题。Django在提交表单时引发ValueError(特别是“无法在没有主键的情况下强制保存()中更新”)。它为什么要这样做,我怎样才能解决这个问题

邮寄表格:

class PostForm(forms.ModelForm):

    def __init__(self,  *args, **kwargs):
        super().__init__(*args, **kwargs)
        for key in ['postTitle', 'postContent', 'category']:
            self.fields[key].widget.attrs.update({'class': 'form-control'})         
        self.fields['content'].widget.attrs.update(width='100px', height='50')

    class Meta:
        model = Post
        fields = ('title', 'content', 'category') 
后模型:

class Post(models.Model):
    title = models.CharField(max_length = 100)
    URL = models.SlugField() # slug for url 
    content = models.TextField()
    author = models.ForeignKey(User, on_delete = models.CASCADE, related_name = 'posts') # id of author
    category = models.CharField(max_length = 9, default = 'General') # category the post is in
    creationDate = models.DateTimeField()
编辑视图:

def editPost(request, pk):
    if request.method == 'GET':
        post = get_object_or_404(Post, pk = pk)
        if post.author == request.user:
            form = PostForm(instance = post)
            return render(request, 'editPost.html',  {'form': form, 'post': post})
        else:
            return redirect('viewPost', pk = pk, postURL = post.postURL)
    if request.method == 'POST':
        post = get_object_or_404(Post, pk = pk)
        form = PostForm(request.POST)
        if post.author == request.user:
            if form.is_valid():
                post = form.save(commit=False)
                post.URL = slugify(post.postTitle)
                post.save(update_fields = ['title', 'content', 'category', 'postURL'])
    return redirect('viewAll')

看来你要在这里重新分配职位了。在这方面,

post = get_object_or_404(Post, pk = pk)
post = form.save(commit=False)
您正在从数据库中获取一个Post实例。那么在这一行,

post = get_object_or_404(Post, pk = pk)
post = form.save(commit=False)
您正在将post变量重新分配给post的未保存实例,该实例仅填充request.post中可用的数据。然后,当您想使用如下参数保存此帖子时:

post.save(update_fields = ['title', 'content', 'category', 'postURL'])

ValueError被引发,因为您试图保存的Post实例没有id,它只有请求中可用的内容。Post

我以前没有使用过表单,但是您能确认是哪一行导致了这里的异常吗?它可能是在post=form.save(commit=False)行上引发的吗?它是在最后一个form.save()行上引发的。这是我的怀疑。确定-我将它从
form=PostForm(request.post)
更改为form=PostForm(request.post,instance=post)`。现在再问另一个愚蠢的问题,因为我在安全性方面非常糟糕-更改这行代码会不会打开我可能不知道的安全漏洞?@vjwvebjkwev我不确定,以前没有使用过表单,但是如果我向/posts/5发送一个post请求(假设我是id为5的帖子的作者),代码将如何运行,但是在请求POST数据中提供另一个id?我可以将另一篇文章的作者字段更改为我的用户吗?一般来说,用django表单更新模型实例似乎不是最好的做法!(这就是为什么我说我在安全性方面不是最好的…:p)我添加了一行代码,用于检查当前用户的表单实例(带有request.POST)以及主POST变量。