如何将表单中的用户字段设置为当前登录的用户?

Posted

技术标签:

【中文标题】如何将表单中的用户字段设置为当前登录的用户?【英文标题】:How do I set user field in form to the currently logged in user? 【发布时间】:2013-08-17 06:24:30 【问题描述】:

我正在制作一个选举信息应用程序,我希望允许当前登录的用户能够在选举中声明自己并且仅他自己作为候选人。

我正在使用 Django 的内置 ModelForm 和 CreateView。我的问题是 Run for Office 表单(换句话说,“创建候选人”表单)允许用户选择数据库中的 any 用户来制作候选人。

我希望 Run for Office 中的用户字段自动设置为当前登录的用户,并隐藏此值,以便登录用户无法将该字段的值更改为其他人。

views.py

class CandidateCreateView(CreateView):
    model = Candidate
    form_class = CandidateForm
    template_name = 'candidate_create.html'

    def form_valid(self, form):
        f = form.save(commit=False)
        f.save()
        return super(CandidateCreateView, self).form_valid(form)

forms.py

class CandidateForm(forms.ModelForm):
    class Meta:
        model = Candidate

models.py

class Candidate(models.Model):
    user = models.ForeignKey(UserProfile)
    office = models.ForeignKey(Office)
    election = models.ForeignKey(Election)
    description = models.TextField()

    def __unicode__(self):
        return unicode(self.user)

    def get_absolute_url(self):
        return reverse('candidate_detail', kwargs='pk': str(self.id))

【问题讨论】:

【参考方案1】:

假设

    我们不想设置null=True,因为我们不想在模型和/或数据库级别允许null 用户

    我们不想设置blank=True 来破坏模型的可读性,因为用户实际上不会是空白的

@nbm.ten 解决方案是一个很好的解决方案。它比其他使用 model 在 nbm.ten 中设置用户(如 this one)的问题的“解决方案”具有优势,不会破坏上述假设。我们不想弄乱模型来解决视图中的问题!

但这里我根据 django 文档 (Models and request.user) 添加了另外两个解决方案:

另外两种解决方案

1。使用通用的 CreateView

from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.edit import CreateView
from myapp.models import Candidate

class CandidateCreate(LoginRequiredMixin, CreateView):
    model = Candidate
    exclude = ['user']

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super().form_valid(form)

2。使用基于类的视图

class CandidateForm(ModelForm):
    class Meta:
        model = Candidate
        exclude = [ 'user',]

class CandidateAddView(LoginRequiredMixin, View):
    def get(self, request, *args, **kwargs):
        form = CandidateForm()
        context = 'form':form
        return render(request, 'myapp/addcandidateview.html', context)
    
    def post(self, request, *args, **kwargs):
           
        form = CandidateForm(request.POST)
        form.instance.user = request.user
        if form.is_valid():
            form.save()
            return redirect(reverse('myapp:index'))

注意事项

请注意,LoginRequiredMixin 会阻止未登录的用户访问表单。如果我们忽略这一点,我们将需要处理form_valid()post() 中的未授权用户。

还有exclude = ['user'] 阻止用户字段显示在表单上。

我们使用form.instance.user 设置用户不是form.dataform.cleaned_data 他们不起作用

【讨论】:

您可能应该提到“通用创建视图”是一个基于类的视图,它可以在您所谓的“基于类的视图”中完成您正在做的所有工作,只有更多的抽象和理智默认值。【参考方案2】:

    从呈现的表单中删除用户字段(使用 excludefields、https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#selecting-the-fields-to-use)

    class CandidateForm(forms.ModelForm):
        class Meta:
            model = Candidate
            exclude = ["user"]
    

    在创建视图中查找用户配置文件并设置用户字段。

    class CandidateCreateView(CreateView):
        ...
        def form_valid(self, form):
            candidate = form.save(commit=False)
            candidate.user = UserProfile.objects.get(user=self.request.user)  # use your own profile here
            candidate.save()
            return HttpResponseRedirect(self.get_success_url())
    

【讨论】:

当,这很容易。我之前尝试过诸如“candidate.user = self.request.user”之类的东西,但显然这不起作用。这将对我必须制作的其他表格派上用场,非常感谢! 为什么 Candidate.user = self.request.user 不工作? self.request.user 不也是一个用户对象吗? 因为 self.request.user 是 User 实例,而 Candidate.user 是 UserProfile 实例。 这种方法会将用户整合到表单本身***.com/questions/4141408/… 我用的是脆的形式。我必须将最后一行更改为 'return super(CandidateCreateView, self).form_valid(form)' 才能使重定向起作用。

以上是关于如何将表单中的用户字段设置为当前登录的用户?的主要内容,如果未能解决你的问题,请参考以下文章

Django formset 设置当前用户

使用从 VBA 代码派生的值填充表中的字段

Django allauth 自定义登录表单未呈现自定义用户模型中的所有字段

谷歌浏览器如何识别登录表单?

Cakephp 3 - 如何在验证过程中检索“表”类中的当前登录用户?

如何将当前登录的用户指定为模型字段的默认值?