在Django ModelForm中使用request.user

26 投票
4 回答
18744 浏览
提问于 2025-04-17 08:10

我在处理登录用户和Django的ModelForm时遇到了一些问题。我有一个叫_Animal_的类,它有一个指向UserForeignKey,还有一些与动物相关的数据,比如年龄、品种等等。

用户可以向数据库添加动物,我需要记录每个动物的创建者,所以在用户创建动物实例时,我需要添加当前登录的用户,也就是request.user

models.py

class Animal(models.Model):
    name = models.CharField(max_length=300)
    age = models.PositiveSmallIntegerField()
    race = models.ForeignKey(Race)
    ...
    publisher = models.ForeignKey(User)
    def __unicode__(self):
        return self.name

class AnimalForm(ModelForm):
    class Meta:
        model = Animal

我的主要目标是隐藏表单中的发布者字段,并在点击保存按钮时提交当前登录的用户。

我可以在视图中使用initial来获取当前用户,但我还希望不显示这个字段。

views.py

@login_required
def new_animal(request):
    if request.method == "POST":
        form = AnimalForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/')
        else:
            variables = RequestContext(request, {'form': form})
            return render_to_response('web/animal_form.html', variables)
    else:
        form = AnimalForm(initial={'publisher': request.user})
    variables = RequestContext(request, {'form': form})
    return render_to_response('web/animal_form.html', variables)

4 个回答

4

我建议直接把它加到表单里:

class AnimalForm(ModelForm):
    class Meta:
        model = Animal
        exclude = ('publisher',)

    def save(self, commit=True):
        self.instance.publisher = self.request.user
        return super().save(commit=commit)

在我看来,这样做是最简洁的版本,而且你可以在不同的视图中使用这个表单。

9

还有一种方法(稍微简短一点):
你需要把这个字段也排除在外:

class AnimalForm(ModelForm):
    class Meta:
        model = Animal
        exclude = ('publisher',)

然后在视图中:

animal = Animal(publisher=request.user)  
form = AnimalForm(request.POST, instance=animal)
if form.is_valid():
     animal.save()
46

你只需要把它从表单中排除,然后在视图里设置它。

class AnimalForm(ModelForm):
    class Meta:
        model = Animal
        exclude = ('publisher',)

... 然后在视图里:

    form = AnimalForm(request.POST)
    if form.is_valid():
        animal = form.save(commit=False)
        animal.publisher = request.user
        animal.save()

(另外要注意的是,第一个 else 语句 - 紧接着重定向的那几行 - 是不必要的。如果你把它去掉,程序会直接执行视图最后的两行代码,这两行是一样的。)

撰写回答