2010-02-10 7 views
54

У меня есть форму с электронной почтой. При использовании {{form.email}} в случае какой-либо ошибки проверки, Джанго все еще оказывает предыдущее значение атрибута значения входного тега:Отображать значение поля формы django в шаблоне?

<input type="text" id="id_email" maxlength="75" class="required" value="[email protected]" name="email"> 

Я хочу, чтобы сделать вход помечать себя (добавить некоторый JavaScript код и класс ошибки в случае ошибки). Например, это мой шаблон вместо {{}} form.email:

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

Однако это не отображает errorneous значение («[email protected]» в данном примере) пользователю. Как получить значение поля в шаблоне?

ответ

5

Решение, предложенное Йенсом, является правильным. Однако, оказывается, что если вы инициализировать ModelForm с экземпляра (пример ниже) Джанго не заполнит данные:

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() 
+0

Я не понимаю, почему django не делает этого по умолчанию ... Я думаю, что я отправлю патч и посмотрю, что говорят об этом люди. –

0
{{form.fields.email}} 
+0

Это дает:

+0

Вы можете написать чтобы получить значение. – shanyu

+0

нет встроенного способа его получить? –

13

У меня есть простое решение для вас!

{{ 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}) 

Надежда, что помогает. Если у вас есть какие-либо вопросы, пожалуйста, дайте мне знать.

+0

Очищенные данные не будут содержать поле электронной почты, если оно не может быть очищено во время проверки. – shanyu

+0

Вы правы. Вы не сможете получить доступ к cleaned_data, если is_valid() терпит неудачу. Я ищу другое решение. – Jens

+0

Я обновил свой код. Было простое решение. Вместо cleaned_data просто используйте данные. Это сработало, даже если проверка не удалась! – Jens

11

Это похоже на работу.

{{ form.fields.email.initial }} 
+3

Это тот, который работал на меня. – PKKid

+7

Я могу ошибаться, но я считаю, что каждый раз будет показывать начальное значение. Например, попробуйте отправить форму, чтобы она выдала ошибку, и вы увидите, что форма, которая перезагружает отображаемую ошибку, будет иметь начальное значение снова, а не значение, которое пользователь вложил, прежде чем он выкинул ошибку. – mlissner

1

Если вы заселены форма с экземпляром, а не с данными POST (как предложенный ответ требует), вы можете получить доступ к данным, используя {{form.instance.my_field_name}}.

36

Вы можете сделать это из шаблона с чем-то вроде этого:

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

Это будет отображать значение экземпляра (если форма создается с помощью, например, вы можете использовать первоначальный вместо этого, если вам нравится), или иначе отобразить данные POST, например, при возникновении ошибки проверки.

+2

стыдно, что этот ответ похоронен так глубоко! Это способ сделать это без добавления какого-либо кода в ваш проект или исправления вашего джанго. –

+1

Можете ли вы рассказать о том, что я заполняю тем, кто заполняет поля? Я попробовал несколько вариантов, и он не сработал. – jordaninternets

5

{{}} form.field_name.value работает для меня

+0

Зависит от вашей версии. Это работает в Django 1.3. Новая функция: https://docs.djangoproject.com/en/dev/ref/forms/api/#django.forms.BoundField.value – mlissner

2

Я хотел, чтобы отобразить значение formset поля. Я пришел к выводу это решение, которое должно работать для нормальных форм тоже:

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

Вышеуказанные решения не работали очень хорошо для меня, и я сомневаюсь, что они будут работать в случае префиксами форм (например, колдунов и FormSets) , Решения, использующие {{ form.data.email }}, не могут работать, потому что это поиск в словаре, и с префиксными формами имя вашего поля будет выглядеть примерно так: «1-email» (мастер и префикс) или «form-1-email» (formet) , а знак минус (-) не допускается в точечных выражениях с точками.

{{form.field_name.value}} только Django 1.3+.

99

Это был запрос функции, который был исправлен в 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 вы используете, она сообщит вам, когда вы выполните команду сервера.

Если вы на что-то ранее до 1.3, вы можете, вероятно, использовать исправление размещены в вышеприведенной ошибке: https://code.djangoproject.com/ticket/10427#comment:24

+0

Это правильный ответ для Django> = 1.3. Это явно отсутствовало в документации django, но теперь она выглядит исправленной (по крайней мере, в версии dev). https://code.djangoproject.com/ticket/16851 – zlovelady

+17

Это имеет неприятный эффект, который, если 'form.field.value' является' None', тогда будет отображаться текст «None». Чтобы отобразить пустую строку вместо этого, используйте '{{form.field.value | default_if_none:" "}}' – cberzan

+0

+1 для упоминания об этом работает только в> = 1.3. Я все еще бегу 1,2, и не мог понять, почему он не работал, пока я не прочитал это. – Wipqozn

0

Я попробовал несколько из перечисленных возможностей, и это, как я решить мою проблему:

#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}) 

Это то, что получает ATTRIB значение, например:

<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> 
Смежные вопросы