2009-05-01 26 views
85

Tôi đang cố gắng đặt trường thành một giá trị nhất định sau khi biểu mẫu được khởi tạo.Giá trị trường đặt Django sau khi biểu mẫu được khởi tạo

Ví dụ: tôi có lớp sau.

class CustomForm(forms.Form): 
    Email = forms.EmailField(min_length=1, max_length=200) 

Trong giao diện, tôi muốn để có thể làm điều gì đó như thế này:

form = CustomForm() 
form["Email"] = GetEmailString() 

return HttpResponse(t.render(c)) 

Trả lời

105

Vì bạn đang không đi qua trong dữ liệu POST, tôi sẽ giả định rằng những gì bạn đang cố gắng làm được đặt giá trị ban đầu sẽ được hiển thị trong biểu mẫu. Cách bạn làm điều này là với từ khóa initial.

form = CustomForm(initial={'Email': GetEmailString()}) 

Xem Django Form docs để được giải thích thêm.

Nếu bạn đang cố gắng thay đổi một giá trị sau khi các hình thức đã được gửi, bạn có thể sử dụng một cái gì đó như:

if form.is_valid(): 
    form.cleaned_data['Email'] = GetEmailString() 

Kiểm tra các tài liệu tham khảo trên để biết thêm về việc sử dụng cleaned_data

+0

Đó chính là điều tôi muốn làm. Cảm ơn! – Eldila

+0

Cảm ơn, đối với tôi quá chính xác những gì tôi cần .. – Neo

+1

Điều này xác nhận những gì tôi biết, nhưng 'ModelChoiceField' của tôi vẫn đang cung cấp invalid_choice khi tôi cung cấp cho nó giá trị' initial': ( –

-12

Một cách khác để làm điều này , nếu bạn đã khởi tạo biểu mẫu (có hoặc không có dữ liệu) và bạn cần thêm dữ liệu khác trước khi hiển thị:

form.data['Email] = GetEmailString() 
+8

Điều này không thành công cho tôi Tôi có một dòng giống như trên trong phương thức __init__ của tôi, và nó làm tăng "AttributeError: Ví dụ QueryDict này là bất biến" –

+0

Mã này chỉ hoạt động khi biểu mẫu đã được initia mà không có bất kỳ dữ liệu biểu mẫu nào. Kết quả là, một đối tượng bất biến như request.GET hoặc request.POST sẽ không bị ràng buộc, vì vậy bạn sẽ nhận được một từ điển trống (form.data) có thể thay đổi mà không có bất kỳ lỗi nào. FYI Tôi đang sử dụng Django 1.6.3 – potar

+0

Điều này sẽ hoạt động nếu tiêu đề "Content-Type" của bạn được đặt thành "multipart/form-data".Nó không thành công khi bạn sử dụng kiểu nội dung của "application/x-www-form-urlencoded". Tôi không biết tại sao, nhưng đó là một ***** để gỡ lỗi. – teewuane

74

Nếu bạn đã khởi tạo đã tạo biểu mẫu, bạn có thể sử dụng thuộc tính ban đầu của trường. Ví dụ,

form = CustomForm() 
form.fields["Email"].initial = GetEmailString() 
+10

Cảm ơn. Trong khi câu trả lời được chấp nhận là cách được đề xuất, bạn giành được giải thưởng "thực sự đã trả lời câu hỏi". Đây là những gì tôi đang tìm kiếm (và những gì xuất hiện trong google). – jason

+0

Cũng hoạt động tốt trong một vòng lặp for với một formset, chỉ cần sử dụng logic "cho form trong formset" và bạn có thể thiết lập các lựa chọn và dữ liệu ban đầu như đã thấy ở trên. – radtek

+5

Có cách nào khác để làm điều này là Django 1.7/Python 3.4? Điều này không có tác dụng đối với tôi – Jeremy

5

Something như Nigel Cohen sẽ làm việc nếu bạn đã bổ sung thêm dữ liệu vào một bản sao của tập thu của hình thức dữ liệu:

form = FormType(request.POST) 
if request.method == "POST": 
    formcopy = form(request.POST.copy()) 
    formcopy.data['Email'] = GetEmailString() 
+1

Tôi không phải là người hâm mộ lớn về việc ghi đè dữ liệu thô. Nếu bạn hoàn toàn phải làm điều này, bạn có lẽ nên làm 'dữ liệu [form.add_prefix ('Email')]' để giải thích cho các trường hợp tiền tố được đặt. – Josh

+2

Có cách nào khác để làm điều này là Django 1.7/Python 3.4? Điều này không làm việc cho tôi – Jeremy

+0

Dòng thứ ba có thể ngắn hơn một chút nếu không cần phải giữ nguyên dạng gốc: 'form.data = form.data.copy()' – ZZY

6

Nếu bạn muốn làm điều đó trong biểu mẫu của __init__ phương pháp đối với một số lý do, bạn có thể thao tác các initial dict:

class MyForm(forms.Form): 
    my_field = forms.CharField(max_length=255) 

    def __init__(self, *args, **kwargs): 
     super(MyForm, self).__init__(*args, **kwargs) 
     self.initial['my_field'] = 'Initial value' 
0

Chỉ cần thay đổi lĩnh vực Form.data của bạn:

class ChooseProjectForm(forms.Form): 
    project = forms.ModelChoiceField(queryset=project_qs) 
    my_projects = forms.BooleanField() 

    def __init__(self, *args, **kwargs): 
     super(ChooseProjectForm, self).__init__(*args, **kwargs) 
     self.data = self.data.copy() # IMPORTANT, self.data is immutable 
     # any condition: 
     if self.data.get('my_projects'): 
      my_projects = self.fields['project'].queryset.filter(my=True) 
      self.fields['project'].queryset = my_projects 
      self.fields['project'].initial = my_projects.first().pk 
      self.fields['project'].empty_label = None # disable "-----" 
      self.data.update(project=my_projects.first().pk) # Update Form data 
      self.fields['project'].widget = forms.HiddenInput() # Hide if you want 
Các vấn đề liên quan