템플릿에 Django 양식 필드의 값을 어떻게 표시합니까?


80

이메일 속성이있는 양식이 있습니다.

{{ form.email }}일부 유효성 검사 오류가 발생한 경우 사용할 때 Django는 입력 태그의 값 속성에서 이전 값을 계속 렌더링합니다.

<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사용자에게 잘못된 값 ( 이 예에서)을 표시하지 않습니다 .

템플릿에서 필드 값을 가져 오려면 어떻게합니까?


답변:


130

이것은 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()방법이지만, 장고 템플릿 ()Jinja2에서 메서드 호출이 명시 적으로있는 동안,의 생략된다.

실행중인 Django 버전을 알고 싶다면 runserver 명령을 수행 할 때 알려줍니다.

1.3 이전 버전을 사용 중이라면 위 버그에 게시 된 수정 사항을 사용할 수 있습니다. https://code.djangoproject.com/ticket/10427#comment:24


이것은 Django> = 1.3에 대한 정답입니다. 이것은 django 문서에서 눈에 띄게 누락되었지만 이제는 수정 된 것으로 보입니다 (적어도 dev 버전에서는). code.djangoproject.com/ticket/16851
zlovelady

19
이 경우 그 불쾌한 효과가 form.field.value있다 None, 다음 텍스트 "없음"이 표시됩니다. 대신 빈 문자열을 표시하려면{{ form.field.value|default_if_none:"" }}
cberzan

이것을 언급하는 +1은> = 1.3에서만 작동합니다. 나는 여전히 1.2를 실행하고 있으며 이것을 읽을 때까지 작동하지 않는 이유를 알 수 없습니다.
Wipqozn

{{ form.initial.fieldname }}여기서 작업하기 (Django 1.2.3).
santiagopim

1
@santiagopim이 잘못되었을 수 있지만, 사용자 입력 값을 제공하는 대신 매번 초기 값을 제공 할 것이라고 믿습니다. 예를 들어, 제출되는 대신 오류가 발생하는 양식을 작성하면 사용자의 입력을 유지하는 대신 제출 후 사용자의 입력이 초기 값으로 전환 된 것을 볼 수 있습니다.
mlissner

42

다음과 같이 템플릿에서이 작업을 수행 할 수 있습니다.

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

그러면 인스턴스 값이 표시됩니다 (양식이 인스턴스로 생성 된 경우 원하는 경우 이니셜을 대신 사용할 수 있음). 그렇지 않으면 유효성 검사 오류가 발생할 때와 같은 POST 데이터가 표시됩니다.


2
이 대답이 너무 깊이 묻혀서 안타깝습니다! 이것은 프로젝트에 코드를 추가하거나 django를 패치하지 않고 수행하는 방법입니다.
w--

2
내가 채우고있는 필드를 필드로 확장 할 수 있습니까? 몇 가지 변형을 시도했지만 작동하지 않았습니다.
jordaninternets 2012-06-04

17

이것은 작동하는 것 같습니다.

{{ form.fields.email.initial }}

11
착각 할 수 있지만 매번 초기 값을 보여줄 것이라고 생각합니다. 예를 들어, 오류가 발생하도록 양식을 제출하면 오류를 표시하는 다시로드되는 양식이 사용자가 오류를 던지기 전에 입력 한 값이 아닌 초기 값을 다시 갖게되는 것을 볼 수 있습니다.
mlissner 2015

16

나는 당신을위한 간단한 해결책이 있습니다!

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

도움이되기를 바랍니다. 질문이 있으시면 알려주십시오.


유효성 검사 중에 정리할 수없는 경우 정리 된 데이터에는 이메일 필드가 포함되지 않습니다.
shanyu 2010

당신이 옳습니다. is_valid ()가 실패하면 clean_data에 액세스 할 수 없습니다. 다른 해결책을 찾고 있습니다.
Jens

코드를 업데이트했습니다. 간단한 해결책이있었습니다. clean_data 대신 단순히 데이터를 사용하십시오. 유효성 검사가 실패하더라도 작동했습니다!
Jens

데이터가 나를 위해 작동하지 않습니다 ... {{form.description}}이 올바른 값을 가진 컨트롤을 제공합니다 {{form.data.description}}이 비어 있습니다 (사실 {{form.data}}가 {}를 반환 함))
에 란 투쟁

btw, 다음을 수행하여 양식을 초기화하고 있습니다. form_details = forms.UserDetailsForm (instance = request.user)
Eran Kampf


5

Jens가 제안한 솔루션이 맞습니다. 그러나 인스턴스 (아래 예)로 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가 기본적으로 이것을하지 않는지 모르겠습니다. 저는 패치를 제출하고 사람들이 그것에 대해 말하는 것을 볼 것이라고 생각합니다.
Eran Kampf

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>

2

POST 데이터가 아닌 인스턴스로 양식을 채운 경우 (제안 된 답변에서 요구하는대로) {{form.instance.my_field_name}}을 사용하여 데이터에 액세스 할 수 있습니다.


2

formset 필드의 값을 표시하고 싶었습니다. 이 솔루션은 일반 형식에서도 작동합니다.

{% 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+ 전용입니다.



-1
{{form.fields.email}}

이것은 다음을 제공합니다 : <django.forms.fields.RegexField object at 0x083235B0>
Eran Kampf

값을 가져 오는 필터를 작성할 수 있습니다.
shanyu 2010

그것을 얻을 수있는 내장 된 방법이 없습니까?
Eran Kampf
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.