2010-02-10 40 views
54

Tôi có biểu mẫu có thuộc tính email. Khi sử dụng {{form.email}} trong trường hợp của một số xác nhận lỗi, django vẫn ám chỉ rằng giá trị trước đó trong thuộc tính giá trị thẻ đầu vào của:Giá trị hiển thị của trường biểu mẫu django trong mẫu?

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

Tôi muốn làm cho đầu vào tag bản thân mình (thêm một số javascript mã và một lớp lỗi trong trường hợp có lỗi). Ví dụ: đây là mẫu của tôi thay vì {{form.email}}:

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

Tuy nhiên điều này không hiển thị giá trị sai ("[email protected]" trong ví dụ này) cho người dùng. Làm cách nào để lấy giá trị của trường trong mẫu?

Trả lời

5

Giải pháp do Jens đề xuất là chính xác. Tuy nhiên, nó chỉ ra rằng nếu bạn khởi ModelForm của bạn với một dụ (ví dụ dưới đây) django sẽ không cư dữ liệu:

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) 

Vì vậy, tôi làm lớp cơ sở ModelForm riêng tôi thao tác trên dữ liệu ban đầu:

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) 

Sau đó, quan điểm ví dụ đơn giản như sau:

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

Tôi không hiểu tại sao django không làm điều này theo mặc định ... Tôi nghĩ rằng tôi sẽ gửi một bản vá và xem mọi người nói gì về nó. –

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

Điều này cho phép:

+0

Bạn có thể viết một lọc để tìm nạp giá trị. – shanyu

+0

không có cách tích hợp để tải xuống? –

13

Tôi có một giải pháp đơn giản dành cho bạn!

{{ form.data.email }} 

Tôi đã thử cách này và hoạt động. Điều này yêu cầu chế độ xem của bạn để điền vào lớp biểu mẫu với dữ liệu POST.

dụ Rất đơn giản:

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

Hy vọng rằng sẽ giúp bạn. Nếu có thắc mắc gì xin cứ hỏi tôi.

+0

Dữ liệu đã được làm sạch sẽ không chứa trường email nếu nó không thể được làm sạch trong quá trình xác nhận. – shanyu

+0

Bạn nói đúng. Bạn sẽ không thể truy cập clean_data nếu is_valid() không thành công. Tôi đang tìm một giải pháp khác. – Jens

+0

Tôi đã cập nhật mã của mình. Có một giải pháp đơn giản. Thay vì clean_data, chỉ cần sử dụng dữ liệu. Điều đó làm việc ngay cả khi xác thực không thành công! – Jens

11

Điều này dường như làm việc.

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

Đây là một trong đó làm việc cho tôi. – PKKid

+7

Tôi có thể bị nhầm lẫn, nhưng tôi tin rằng sẽ hiển thị giá trị ban đầu mỗi lần. Ví dụ, hãy thử gửi biểu mẫu để nó ném một lỗi và bạn sẽ thấy biểu mẫu tải lại hiển thị lỗi sẽ có giá trị ban đầu một lần nữa, không phải giá trị mà người dùng đưa vào trước khi nó ném lỗi. – mlissner

1

Nếu bạn đã điền biểu mẫu với cá thể và không có dữ liệu POST (như câu trả lời được đề xuất yêu cầu), bạn có thể truy cập dữ liệu bằng {{form.instance.my_field_name}}.

36

Bạn có thể làm điều này từ mẫu với một cái gì đó như thế này:

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

này sẽ hiển thị giá trị ví dụ (nếu mẫu được tạo ra với một ví dụ, bạn có thể sử dụng ban đầu thay vì nếu bạn thích), hoặc khác hiển thị dữ liệu POST như khi xảy ra lỗi xác thực.

+2

một sự xấu hổ câu trả lời này được chôn sâu như vậy! Đây là cách để làm điều đó mà không cần thêm bất kỳ mã nào vào dự án của bạn hoặc vá django của bạn. –

+1

Bạn có thể mở rộng những gì tôi đang điền vào những trường được tạo ra không? Tôi đã thử một vài biến thể và nó đã không hoạt động. – jordaninternets

5

{{form.field_name.value}} phù hợp với tôi

+0

Phụ thuộc vào phiên bản của bạn. Điều đó làm việc trong Django 1.3. Tính năng mới: https://docs.djangoproject.com/en/dev/ref/forms/api/#django.forms.BoundField.value – mlissner

2

Tôi muốn hiển thị giá trị của trường biểu mẫu. Tôi kết luận giải pháp này, mà nên làm việc cho các hình thức bình thường quá:

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

Các giải pháp trên không làm việc rất tốt cho tôi, và tôi nghi ngờ họ sẽ làm việc trong trường hợp của các hình thức tiền tố (ví dụ như trình thuật sĩ và formsets) . Các giải pháp sử dụng {{ form.data.email }} không thể hoạt động, vì đây là tra cứu từ điển và với các mẫu tiền tố, tên trường của bạn sẽ giống như '1 email' (trình hướng dẫn và mẫu tiền tố) hoặc 'form-1-email' (formset) và dấu trừ (-) không được cho phép trong các biểu thức tra cứu mẫu rải rác.

{{form.field_name.value}} chỉ là Django 1.3+.

99

Đây là yêu cầu tính năng đã được sửa trong Django 1.3.

Dưới đây là các lỗi: https://code.djangoproject.com/ticket/10427

Về cơ bản, nếu bạn đang chạy một cái gì đó sau 1.3, trong Django mẫu bạn có thể làm:

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

Hoặc trong Jinja2:

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

Note rằng field.value() là một phương pháp, nhưng trong các mẫu Django () bị bỏ qua, trong khi trong các cuộc gọi phương thức Jinja2 thì rõ ràng.

Nếu bạn muốn biết phiên bản Django nào bạn đang chạy, nó sẽ cho bạn biết khi nào bạn thực hiện lệnh runserver.

Nếu bạn đang ở trên một cái gì đó trước khi 1.3, bạn có thể có thể sử dụng sửa chữa posted in lỗi trên: https://code.djangoproject.com/ticket/10427#comment:24

+0

Đây là câu trả lời đúng cho Django> = 1.3. Điều này rõ ràng là vắng mặt từ tài liệu django, nhưng bây giờ dường như đã được cố định (ít nhất là trong phiên bản dev). https://code.djangoproject.com/ticket/16851 – zlovelady

+17

Điều này có hiệu ứng khó chịu nếu 'form.field.value' là' None', thì văn bản "Không" sẽ được hiển thị. Để hiển thị một chuỗi rỗng thay vào đó, hãy sử dụng '{{form.field.value | default_if_none:" "}}' – cberzan

+0

+1 để đề cập đến công việc này chỉ> = 1,3. Tôi vẫn đang chạy 1,2, và không thể hiểu tại sao nó không hoạt động cho đến khi tôi đọc nó. – Wipqozn

0

Tôi đã thử một vài trong số các khả năng đề cập, và đây là cách tôi giải quyết vấn đề của tôi:

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

Tôi cố gắng để giải thích điều này theo một cách sao cho người mới bắt đầu có thể tìm thấy nó dễ dàng hơn để hiểu. Hãy chú ý đến các 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}) 

Đó là những gì được attrib giá trị, ví dụ:

<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> 
Các vấn đề liên quan