2010-02-10 40 views
14

Làm cách nào để thêm lỗi vào đầu biểu mẫu sau khi tôi xóa dữ liệu? Tôi có một đối tượng cần thực hiện cuộc gọi REST tới ứng dụng bên ngoài (google maps) làm điều kiện lưu trước và điều này có thể không thành công, có nghĩa là tôi cần người dùng của mình sửa dữ liệu trong biểu mẫu. Vì vậy, tôi làm sạch các dữ liệu và sau đó cố gắng tiết kiệm và thêm vào các lỗi hình thức nếu tiết kiệm không hoạt động:thêm lỗi vào lỗi biểu mẫu Django .__ all__

if request.method == "POST": 
#clean form data 
    try: 
     profile.save() 
     return HttpResponseRedirect(reverse("some_page", args=[some.args])) 
    except ValueError: 
     our_form.errors.__all__ = [u"error message goes here"] 
return render_to_response(template_name, {"ourform": our_form,}, 
     context_instance=RequestContext(request)) 

này thất bại trong việc trả lại văn bản sai sót trong đơn vị xét nghiệm của tôi (mà đang tìm kiếm nó trong {{form.non_field_errors}}), và sau đó khi tôi chạy nó thông qua trình gỡ lỗi, các lỗi đã không được thêm vào dict lỗi biểu mẫu khi chúng đạt đến dòng render_to_response, cũng như bất kỳ nơi nào khác trong cây our_form. Tại sao điều này không hiệu quả? Làm cách nào để thêm lỗi vào đầu biểu mẫu sau khi được xóa?

Trả lời

9

Bạn nên tăng xác thực.

Tại sao không đặt xác minh trong phương pháp sạch của hình thức

class ProfileForm(forms.Form): 
    def clean(self): 
     try: 
      #Make a call to the API and verify it works well 
     except: 
      raise forms.ValidationError('Your address is not locatable by Google Maps') 

theo cách đó, bạn chỉ cần chuẩn form.is_valid() trong giao diện.

+1

Thật không may nó phải có hệ thống hơn, bản cập nhật này có thể xảy ra khi các phần khác của hệ thống cố gắng thay đổi dữ liệu, vì vậy nó không chỉ là một hình thức. Nếu không, bạn nói đúng, biểu mẫu sẽ là lý tưởng. – hendrixski

+0

Không phải lúc nào cũng sử dụng biểu mẫu được kế thừa để thực hiện xác thực không? –

18

Bạn thực sự muốn thực hiện điều này trong quá trình xác thực biểu mẫu và tăng ValidationError từ đó ... nhưng nếu bạn đã đặt làm theo cách này, bạn sẽ muốn truy cập _errors để thêm thư mới. Hãy thử một cái gì đó như thế này:

from django.forms.util import ErrorList 

our_form._errors["field_name"] = ErrorList([u"error message goes here"]) 
+0

Tôi cần các lỗi ở đầu biểu mẫu vì không phải bất kỳ trường nào có thể khiến lỗi này bị lỗi (ví dụ: tôi đang kết hợp đường phố + thành phố + tiểu bang + mã zip và mã hóa địa lý). – hendrixski

+6

-1 vì điều này không giải quyết được yêu cầu của OP về việc thêm lỗi * phi trường *. Ngoài ra -1 vì phép gán này xóa sạch bất kỳ lỗi nào có thể đã tồn tại cho '_errors [" field_name "]'. – JCotton

+0

Đây có phải là cách phù hợp để làm điều đó không? non_field_errors = [] self._errors ['field_name'] = self._errors.get ('field_name', []) self._errors ['field_name'] = self._errors ['field_name']. _ ("field_name không hợp lệ") #add anyy non field error tăng biểu mẫu.ValidationError (non_field_errors) –

1

Tôi không chắc chắn làm thế nào khủng khiếp của một hack này là (Tôi đã thực sự làm việc trên hai dự án Django cho đến thời điểm này) nhưng nếu bạn làm một cái gì đó như sau bạn nhận được một thông báo lỗi riêng biệt mà không được liên kết với một lĩnh vực cụ thể trong mô hình:

form = NewPostForm() 
if something_went_horribly_wrong(): 
    form.errors[''] = "You broke it!" 
12

lỗi lĩnh vực không thể được thêm vào bằng cách sử dụng liên tục NON_FIELD_ERRORS chìa khóa từ điển (đó là __all__ theo mặc định):

from django import forms 
errors = my_form._errors.setdefault(forms.forms.NON_FIELD_ERRORS, forms.util.ErrorList()) 
errors.append("My error here") 
+2

Điều này khiến đối tượng 'NoneType' không có thuộc tính 'setdefault' cho tôi. Có lẽ mô hình của tôi là hợp lệ và do đó –

+0

Làm việc tốt cho tôi – urig

+2

@MartinProbst: mã này phải được chạy sau khi gọi đến form.is_valid() –

8

Bạn hầu như ở đó với giải pháp ban đầu của mình. Dưới đây là một lớp Mẫu cơ sở tôi đã xây dựng cho phép tôi làm điều tương tự, tức là thêm các thông báo lỗi phi trường để có dạng:

from django import forms 
from django.forms.util import ErrorDict 
from django.forms.forms import NON_FIELD_ERRORS 

class MyBaseForm(forms.Form): 
    def add_form_error(self, message): 
     if not self._errors: 
      self._errors = ErrorDict() 
     if not NON_FIELD_ERRORS in self._errors: 
      self._errors[NON_FIELD_ERRORS] = self.error_class() 
     self._errors[NON_FIELD_ERRORS].append(message) 

class MyForm(MyBaseForm): 
    .... 

Tất cả các hình thức của tôi mở rộng lớp này và vì vậy tôi chỉ có thể gọi add_form_error () để thêm một thông báo lỗi khác.

+0

+1 để kiểm tra các thuộc tính tồn tại và không giả định 'error_class()' là một ErrorList Bạn có thể sử dụng phương thức này để thêm các thông báo lỗi ngoài trường cũng như không có su bclassing Form, có thể phù hợp với các trường hợp sử dụng khác. – JCotton

+0

1.7 có một cái gì đó như thế này được xây dựng trong. –

0

Nếu xác thực liên quan đến lớp dữ liệu, thì bạn thực sự không nên sử dụng xác thực biểu mẫu. Kể từ khi Django 1,2 mặc dù, có tồn tại một khái niệm tương tự cho các mô hình Django và điều này chắc chắn là những gì bạn shoud sử dụng. Xem the documentation for model validation.

10

Trong Django 1,7 hoặc cao hơn, tôi sẽ làm:

form.add_error(field_name, "Some message") 

Phương pháp add_error đã được bổ sung trong 1.7. Biến số form là biểu mẫu tôi muốn thao tác và field_name là tên trường cụ thể hoặc None nếu tôi muốn lỗi không được liên kết với một trường cụ thể.

Trong Django 1.6 tôi sẽ làm một cái gì đó như:

from django.forms.forms import NON_FIELD_ERRORS 

errors = form._errors.setdefault(field_name, form.error_class()) 
errors.append("Some message") 

Trong đoạn mã trên form là hình thức tôi muốn thao tác và field_name là tên trường mà tôi muốn thêm một lỗi. field_name có thể được đặt thành NON_FIELD_ERRORS để thêm lỗi không được liên kết với một trường cụ thể. Tôi sử dụng form.error_class() để tạo danh sách thông báo lỗi trống. Đây là cách Django 1,6 trong nội bộ tạo ra một danh sách sản phẩm nào thay vì nhanh chóng trực tiếp ErrorList().

+0

Hey Louis, cảm ơn bạn rất nhiều vì câu trả lời này, tuyệt vời! –

+0

@Louis, của tôi là 1,8, tôi đã thử "form.add_error (field_name," Một số thông báo ")", sau đó nó báo cáo "'MyForm' đối tượng không có thuộc tính 'addError'", tôi cần phải nhập bất cứ điều gì ngoài "từ django.core.exceptions nhập ObjectDoesNotExist, ValidationError "? –

Các vấn đề liên quan