【问题标题】:How do I display the value of a Django form field in a template?如何在模板中显示 Django 表单字段的值?
【发布时间】:2011-01-15 06:05:32
【问题描述】:

我有一个带有电子邮件属性的表单。

在使用{{ form.email }}时,如果出现一些验证错误,Django 仍然会在输入标签的 value 属性中呈现之前的值:

<input type="text" id="id_email" maxlength="75" class="required"
       value="some@email.com" name="email">

我想自己渲染输入标签(添加一些 JavaScript 代码和错误类以防出错)。例如这是我的模板而不是{{ form.email }}:

<input type="text" autocomplete="on" id="id_email" name="email"
       class="email {% if form.email.errors %} error {% endif %}">

但是,这不会向用户显示错误值(在此示例中为 some@email.com)。

如何获取模板中字段的值?

【问题讨论】:

标签: django django-templates


【解决方案1】:

{{ form.field_name.value }} 为我工作

【讨论】:

【解决方案2】:

Jens 提出的解决方案是正确的。 然而,事实证明,如果你用 instance 初始化你的 ModelForm(下面的例子)django 将不会填充数据:

def your_view(request):   
    if request.method == 'POST':
        form = UserDetailsForm(request.POST)
        if form.is_valid():
          # some code here   
        else:
          form = UserDetailsForm(instance=request.user)

所以,我创建了自己的 ModelForm 基类来填充初始数据:

from django import forms 
class BaseModelForm(forms.ModelForm):
    """
    Subclass of `forms.ModelForm` that makes sure the initial values
    are present in the form data, so you don't have to send all old values
    for the form to actually validate.
    """
    def merge_from_initial(self):
        filt = lambda v: v not in self.data.keys()
        for field in filter(filt, getattr(self.Meta, 'fields', ())):
            self.data[field] = self.initial.get(field, None)

那么,简单视图示例如下所示:

def your_view(request):   if request.method == 'POST':
    form = UserDetailsForm(request.POST)
    if form.is_valid():
      # some code here   
    else:
      form = UserDetailsForm(instance=request.user)
      form.merge_from_initial()

【讨论】:

  • 我不明白为什么 django 默认不这样做......我想我会提交一个补丁,看看人们对此有何看法。
【解决方案3】:

我尝试了一些提到的可能性,这就是我解决问题的方法:

#forms.py
class EditProfileForm(forms.ModelForm):
    first_name = forms.CharField(label='First Name',
                                 widget=forms.TextInput(
                                 attrs={'class': 'form-control'}),
                                 required=False)
    last_name = forms.CharField(label='Last Name',
                                 widget=forms.TextInput(
                                 attrs={'class': 'form-control'}),
                                 required=False)
    # username = forms.CharField(widget=forms.TextInput(
    #                              attrs={'class': 'form-control'}),
    #                              required=True)
    address = forms.CharField(max_length=255, widget=forms.TextInput(
                                 attrs={'class': 'form-control'}),
                                 required=False)
    phoneNumber = forms.CharField(max_length=11,
                                 widget=forms.TextInput(
                                 attrs={'class': 'form-control'}),
                                 required=False)
    photo = forms.ImageField(label='Change Profile Image', required=False)

    class Meta:
        model = User
        fields = ['photo', 'first_name', 'last_name', 'phoneNumber', 'address']
                  # 'username',



#views.py
def edit_user_profile(request, username):
    user = request.user
    username = User.objects.get(username=username)
    user_extended_photo = UserExtended.objects.get(user=user.id)
    form = EditProfileForm(request.POST or None, request.FILES, instance=user)
    user_extended = UserExtended.objects.get(user=user)
    if request.method == 'POST':
        if form.is_valid():
            # photo = UserExtended(photo=request.FILES['photo'] or None, )
            user.first_name = request.POST['first_name']
            user.last_name = request.POST['last_name']
            user_extended.address = request.POST['address']
            user_extended.phoneNumber = request.POST['phoneNumber']
            user_extended.photo = form.cleaned_data["photo"]
            # username = request.POST['username']
            user_extended.save()
            user.save()

            context = {
                'form': form,
                'username': username,
                'user_extended_photo': user_extended_photo,
            }

            return render(request, 'accounts/profile_updated.html', context)
    else:
        photo = user_extended.photo
        first_name = user.first_name
        last_name = user.last_name
        address = user_extended.address
        phoneNumber = user_extended.phoneNumber
        form = EditProfileForm(
            initial={'first_name': first_name, 'last_name': last_name,
                                   'address': address, 'phoneNumber': phoneNumber,
                                   'photo': photo})
    context = {
        'form': form,
        'username': username,
        'user_extended_photo': user_extended_photo,

    }
    return render_to_response('accounts/edit_profile.html', context,
                                 context_instance=RequestContext(request))

#edit_profile.html
  <form action="/accounts/{{ user.username }}/edit_profile/" method="post" enctype='multipart/form-data'>
                                    {% csrf_token %}
                                        <div class="col-md-6">
                                            <div class="form-group">
                                                {{ form.as_p }}
                                            </div>
                                        </div>
                                    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
                                    <button type="submit"  value="Update Profile" class="btn btn-info btn-fill pull-right">Update Profile</button>
                                    <div class="clearfix"></div>
                                </form>

我试图以某种方式解释这一点,以便初学者可能会发现它更容易理解。密切关注else:

        photo = user_extended.photo
        first_name = user.first_name
        last_name = user.last_name
        address = user_extended.address
        phoneNumber = user_extended.phoneNumber
        form = EditProfileForm(
            initial={'first_name': first_name, 'last_name': last_name,
                                  'address': address, 'phoneNumber': phoneNumber,
                                  'photo': photo}) 

它是获取价值属性的东西,例如:

<p><label for="id_first_name">First Name:</label> <input class="form-control" id="id_first_name" name="first_name" type="text" value="Emmanuel" /></p>
<p><label for="id_last_name">Last Name:</label> <input class="form-control" id="id_last_name" name="last_name" type="text" value="Castor" /></p>

【讨论】:

    【解决方案4】:

    这似乎有效。

    {{ form.fields.email.initial }}
    

    【讨论】:

    • 我可能记错了,但我相信每次都会显示初始值。例如,尝试提交表单以使其引发错误,您会看到重新加载显示错误的表单将再次具有初始值,而不是用户在引发错误之前输入的值。
    【解决方案5】:

    在 Django 1.2 上,{{ form.data.field }} 和 {{ form.field.data }} 都可以,但不是 {{ form.field.value }}。
    正如其他人所说,{{ form.field.value }} 仅是 Django 1.3+,但https://docs.djangoproject.com/en/1.3/topics/forms/ 中没有规范。可以在https://docs.djangoproject.com/en/1.4/topics/forms/找到。

    【讨论】:

      【解决方案6】:

      这是 Django 1.3 中修复的功能请求。

      这是错误:https://code.djangoproject.com/ticket/10427

      基本上,如果你在 1.3 之后运行某些东西,在 Django 模板中你可以这样做:

      {{ form.field.value|default_if_none:"" }}
      

      或者在 Jinja2 中:

      {{ form.field.value()|default("") }}
      

      注意field.value() 是一个方法,但在Django 模板中() 被省略,而在Jinja2 中方法调用是显式的。

      如果你想知道你运行的是哪个版本的 Django,它会在你执行 runserver 命令时告诉你。

      如果您使用的是 1.3 之前的版本,您可能可以使用上述错误中发布的修复:https://code.djangoproject.com/ticket/10427#comment:24

      【讨论】:

      • 这是 Django >= 1.3 的正确答案。这在 django 文档中明显没有,但现在看起来已经修复(至少在开发版本中)。 code.djangoproject.com/ticket/16851
      • 如果form.field.valueNone,那么会显示文本“None”。要改为显示空字符串,请使用 {{ form.field.value|default_if_none:"" }}
      • +1 表示仅在 >=1.3 中有效。我仍在运行 1.2,直到我读到这篇文章才弄清楚为什么它不起作用。
      • 在这里使用{{ form.initial.fieldname }} (Django 1.2.3)。
      • 我可能是错的@santiagopim,但我相信每次都会给你初始值,而不是给你用户输入的值。例如,做一个抛出错误而不是提交的表单,你会看到提交后用户的输入切换到初始值,而不是保留用户的输入。
      【解决方案7】:

      我想显示一个表单集字段的值。我总结了这个解决方案,它也适用于正常形式:

      {% if form.email.data %} {{ form.email.data }}
      {% else %} {{ form.initial.email }} 
      {% endif %}
      

      上述解决方案对我来说效果不佳,我怀疑它们是否适用于带前缀的表单(例如向导和表单集)。 使用{{ form.data.email }} 的解决方案不起作用,因为它是字典查找,并且使用前缀表单,您的字段名称看起来像“1-email”(向导和前缀表单)或“form-1-email”(formset ),并且在点分模板查找表达式中不允许使用减号 (-)。

      {{form.field_name.value}} 仅适用于 Django 1.3+。

      【讨论】:

        【解决方案8】:

        您可以使用以下模板从模板中执行此操作:

        {% if form.instance.some_field %}
              {{form.instance.some_field}}
        {% else %}
              {{form.data.some_field}}
        {% endif %}
        

        这将显示实例值(如果表单是使用实例创建的,您可以根据需要使用 initial 代替),或者在发生验证错误时显示 POST 数据。

        【讨论】:

        • 很遗憾这个答案被埋得太深了!这是在不向项目添加任何代码或修补 django 的情况下执行此操作的方法。
        • 你能详细说明我在那些虚构的字段中填写的内容吗?我尝试了一些变体,但都没有奏效。
        【解决方案9】:

        如果您使用实例而不是 POST 数据填充表单(如建议的答案所要求的那样),则可以使用 {{ form.instance.my_field_name }} 访问数据。

        【讨论】:

          【解决方案10】:

          我有一个简单的解决方案给你!

          {{ form.data.email }}
          

          我试过了,效果很好。这需要您的视图使用 POST 数据填充表单类。

          非常简单的例子:

          def your_view(request):
            if request.method == 'POST':
              form = YourForm(request.POST)
              if form.is_valid():
                # some code here
            else:
              form = YourForm()
          
            return render_to_response('template.html', {'form':form})
          

          希望对您有所帮助。如果您有任何问题,请告诉我。

          【讨论】:

          • 如果在验证过程中无法清理,清理后的数据将不包含电子邮件字段。
          • 你是对的。如果 is_valid() 失败,您将无法访问cleaned_data。我正在寻找另一种解决方案。
          • 我更新了我的代码。有一个简单的解决方案。而不是cleaned_data 只是使用数据。即使验证失败,它仍然有效!
          • data 对我不起作用... {{ form.description }} 给出了一个正确值的控件 {{ form.data.description }} 是空的(实际上,{{ form.description }}数据 }} 返回 {})
          • 顺便说一句,我正在初始化表单:form_details = forms.UserDetailsForm(instance=request.user)
          【解决方案11】:
          {{form.fields.email}}
          

          【讨论】:

          • 这给出了:
          • 你可以写一个过滤器来获取值。
          • 没有内置方法可以获取吗?
          猜你喜欢
          • 2012-07-29
          • 1970-01-01
          • 2011-10-11
          • 2017-12-15
          • 2021-07-25
          • 2018-03-21
          • 2013-09-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多