3

As an example, let's take a look at the 'next' parameter in django.contrib.auth

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 . Then, the LoginForm could set this parameter into context_data and generate a form with a hidden input which contains its value like

{% 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? 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.

How could I do this?

4

2 回答 2

5

最后,我自己想通了。

为了解决这个问题,原始基于模板的解决方案中的 context_data 应该传递initialforms.Form.

例如,使用 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

然后,可以在 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
    )
  )
于 2013-09-30T14:49:24.207 回答
1

您可以要求 Django Crispy Form 不渲染<form>标签,而只生成<input>标签,然后您可以添加自己的额外<input>.

您可以通过将表单助手的form_tag属性设置为False.

这一切都在此处详细记录。请注意,与示例不同,您不需要{% crispy second_form %},您只需要在if此处添加自己的块。

于 2013-09-29T10:52:36.647 回答