简体   繁体   English

将 request.user 与 Django ModelForm 一起使用

[英]Using request.user with Django ModelForm

I'm having a problem with logged users and a Django ModelForm .我遇到了登录用户和 Django ModelForm I have a class named _Animal_ that has a ForeignKey to User and some data related to the animal like age, race, and so on.我有一个名为类_Animal_具有ForeignKeyUser和相关的年龄,种族,动物的一些数据,等等。

A user can add Animals to the db and I have to track the author of each animal, so I need to add the request.user that is logged when the user creates an animal instance.用户可以将动物添加到数据库中,我必须跟踪每个动物的作者,因此我需要添加用户创建动物实例时记录的request.user

models.py模型.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

The main goal is hide the publisher field in the form, and submit the logged user when hitting save button.主要目标是隐藏表单中的发布者字段,并在点击保存按钮时提交登录的用户。

I can catch the current user in the view using initial , but what I also want is not display the field.我可以使用initial在视图中捕获当前用户,但我还想要的是不显示该字段。

views.py视图.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)

You just need to exclude it from the form, then set it in the view.您只需要从表单中排除它,然后在视图中设置它。

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

... and in the view: ...并在视图中:

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

(Note also that the first else clause - the lines immediately following the redirect - is unnecessary. If you leave it out, execution will fall through to the two lines at the end of the view, which are identical.) (还要注意第一个else子句 - 紧跟在重定向之后的行 - 是不必要的。如果你省略它,执行将下降到视图末尾的两行,它们是相同的。)

Another way (slightly shorter):另一种方式(略短):
You need to exclude the field as well:您还需要排除该字段:

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

then in the view:然后在视图中:

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

I would add it directly to the form:我会直接将它添加到表单中:

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)

This is in my opinion the cleanest version and you may use the form in different views.在我看来,这是最干净的版本,您可以在不同的视图中使用该表单。

If you are using ModelAdmin you should add method get form on your ModelAdmin如果您使用 ModelAdmin,您应该在 ModelAdmin 上添加方法 get form

class BlogPostAdmin(admin.ModelAdmin):
    form = BlogPostForm

    def get_form(self, request, **kwargs):
        form = super(BlogPostAdmin, self).get_form(request, **kwargs)
        form.request = request
        return from

and you can now access request in your ModelForm您现在可以在 ModelForm 中访问请求

class ProductAdminForm(forms.ModelForm):
    
    def save(self, commit: bool,  *args, **kwargs):
        self.instance.user = self.request.user
        return super().save(commit=commit)
        pass

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM