简体   繁体   English

如何将request.GET中的值作为django-crispy-forms中的隐藏输入

[英]How to put a value from request.GET as a hidden input in django-crispy-forms

As an example, let's take a look at the 'next' parameter in django.contrib.auth 例如,让我们看一下django.contrib.auth中的“ next”参数

If the client is trying to access some resources which is only available for authenticated users, the login url will be modified and attached with extra parameter as ?next=the_next_url . 如果客户端尝试访问某些仅对经过身份验证的用户可用的资源,则将修改登录URL并附加额外的参数?next=the_next_url Then, the LoginForm could set this parameter into context_data and generate a form with a hidden input which contains its value like 然后, LoginForm可以将此参数设置为context_data并生成带有包含其值的隐藏输入的表单,例如

{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}

However, how can I do this if I generate the form completely with django-crispy-form? 但是,如果我完全使用django-crispy-form生成表单,该怎么办? In this case, the template file contains nothing but 在这种情况下,模板文件仅包含任何内容

{% crispy_tag form %}

form will be set as context data, which means I have to push the parameter from request.GET in the form as a hidden input widget. form将被设置为上下文数据,这意味着我必须将来自request.GET的参数作为隐藏的输入小部件推送到表单中。

How could I do this? 我该怎么办?

Finally, I figured it out by myself. 最后,我自己弄清楚了。

To solve this problem, the context_data in the original template based solution should be passed as initial into the constructor of forms.Form . 要解决此问题,应将基于原始模板的解决方案中的context_data作为initial forms.Form传递给forms.Form的构造forms.Form

For example, with django CVB, get_initial is the right point to pass initial data to forms 例如,对于django CVB, get_initial是将初始数据传递到表单的正确点

def get_initial(self):
  initial = Super(ThisCBV, self).get_initial()
  redirect_field_name = self.get_redirect_field_name()
  if (redirect_field_name in self.request.GET and 
      redirect_field_value in self.request.GET):
      initial.update({
           "redirect_field_name": redirect_field_name,
           "redirect_field_value": self.request.REQUEST.get(
               redirect_field_name),
      })
  return initial

Then, it is possible to add a field dynamically in the instance of forms.Form 然后,可以在Forms.Form的实例中动态添加字段。

def __init__(self, *args, **kwargs):
  super(ThisForm, self).__init__(*args, **kwargs)
  if ('redirect_field_name' in kwargs['initial'] and
      'redirect_field_value' in kwargs['initial']):

      self.has_redirection = True
      self.redirect_field_name = kwargs['initial'].get('redirect_field_name')
      self.redirect_field_value = kwargs['initial'].get('redirect_field_value')

      ## dynamically add a field into form
      hidden_field = forms.CharField(widget=forms.HiddenInput())
      self.fields.update({
        self.redirect_field_name: hidden_field
      })

  ## show this field in layout
  self.helper = FormHelper()
  self.helper.layout = Layout(
    Field(
      self.redirect_field_name,
      type='hidden',
      value=self.redirect_field_value
    )
  )

You can ask Django Crispy Form to not render the <form> tag, and only generate the <input> tags, which will let you then add your own extra <input> . 您可以要求Django Crispy Form不呈现<form>标记,而仅生成<input>标记,这将使您可以添加自己的额外<input>

You do this by setting the form helper's form_tag property to False . 您可以通过将表单助手的form_tag属性设置为False

This is all documented in detail here . 此处详细记录了所有内容 Note that unlike the example, you won't need {% crispy second_form %} , you'll only need to add your own if block there. 请注意,与示例不同,您不需要{% crispy second_form %} ,只需要在其中添加自己的if块。

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

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