如何将用户对象传递给 Django 中的表单

Posted

技术标签:

【中文标题】如何将用户对象传递给 Django 中的表单【英文标题】:How to pass user object to forms in Django 【发布时间】:2017-09-06 22:29:54 【问题描述】:

如何将用户对象或请求传递给我的表单以将其用作输入文本框的初始值?

例如,我有我的表单:

class ContactForm(forms.Form):
contact_name = forms.CharField(required=True, initial="???")
contact_email = forms.EmailField(required=True)
subjects = forms.ChoiceField(choices=emailsubjects)
content = forms.CharField(
    required=True,
    widget=forms.Textarea
)

def __init__(self, *args, **kwargs):
    self.request = kwargs.pop("request")
    super(ContactForm, self).__init__(*args, **kwargs)
    self.fields['contact_name'].label = "Your name:"
    self.fields['contact_email'].label = "Your email:"
    self.fields['content'].label = "What do you want to say?"
    self.fields['subjects'].label = "Please, select the subject of your message"

我希望我的 user.first_name 作为contact_name 字段的默认值。

这是我的views.py,我需要表单:

def ContactsView(request):
form_class = ContactForm(request=request)
# new logic!
if request.method == 'POST':
    form = form_class(data=request.POST)

    if form.is_valid():
        contact_name = request.POST.get(
            'contact_name'
            , '')
        contact_email = request.POST.get(
            'contact_email'
            , '')
        form_content = request.POST.get('content', '')
        subjects = form.cleaned_data['subjects']
        subjects = dict(form.fields['subjects'].choices)[subjects]
        # Email the profile with the
        # contact information
        template = get_template('threeD/email/contact_template.txt')
        context = Context(
            'contact_name': contact_name,
            'subjects': subjects,
            'contact_email': contact_email,
            'form_content': form_content,
        )
        content = template.render(context)

        email = EmailMessage(
            "New message from " + contact_name,
            content,
            "Message - " + subjects + ' ',
            ['smart.3d.printing.facility@gmail.com'],
            headers='Reply-To': contact_email
        )
        email.send()
        messages.success(request, "Thank you for your message.")
        return redirect('/index/contacts/')


return render(request, 'threeD/contacts.html', 
    'form': form_class,
)

任何帮助将不胜感激

【问题讨论】:

【参考方案1】:

您需要在视图中传递初始值:

观看次数:

def ContactsView(request):
    form_class = ContactForm(request=request,
                             initial='contact_name': request.user.first_name)
    ...

【讨论】:

【参考方案2】:

您已更改表单以获取请求对象。因此,您可以在表单的方法中访问 self.request.user

class ContactForm(forms.Form):
    ...
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request")
        super(ContactForm, self).__init__(*args, **kwargs)
        self.fields['contact_name'].label = "Your name:"
        self.fields['contact_name'].initial = self.request.user.first_name

您还必须更新视图以传递请求对象。记得更新 GET 和 POST 请求的代码。

if request.method == 'POST':
    form = ContactForm(data=request.POST, request=request)
    ...
else:
    # GET request
    form = ContactForm(request=request)

最后,通过将请求传递给表单,您将它与视图紧密耦合。将user 传递给表单可能会更好。这将使表单与视图分开测试变得更容易。如果您更改表单,请记住也要更新视图。

【讨论】:

太棒了!非常感谢您帮助我!有用!在我看来,我还必须做的一件事是:form_class= ContactForm(request=request) # 新逻辑!如果 request.method == 'POST': form = ContactForm(data=request.POST, request = request) 我必须更改 form = ContactFrom(...) ,而不是我以前的。真的不明白为什么,但它现在可以工作了:/:D 那是因为视图的第一行有错误——应该是form_class = ContactForm。对于这样的基于函数的视图,我认为完全删除该行并改用form = ContactForm(data=request.POST, request = request 会更清楚。

以上是关于如何将用户对象传递给 Django 中的表单的主要内容,如果未能解决你的问题,请参考以下文章

如何将表单视图作为 django 中的上下文传递给另一个视图?

如何自动将用户对象传递给 Symfony 3 表单?

将参数传递给FormView Django中的表单

将参数传递给 django 表单

如何将额外的参数传递给 django admin 自定义表单?

如何正确地将参数传递给rails表单