Django: Biểu mẫu Mô hình "đối tượng không có thuộc tính 'clean_data'"


83

Tôi đang cố gắng tạo một biểu mẫu tìm kiếm cho một trong các lớp học của mình. Mô hình của biểu mẫu là:

from django import forms
from django.forms import CharField, ModelMultipleChoiceField, ModelChoiceField
from books.models import Book, Author, Category

class SearchForm(forms.ModelForm):
    authors = ModelMultipleChoiceField(queryset=Author.objects.all(),required=False)    
    category = ModelChoiceField (queryset=Category.objects.all(),required=False)
    class Meta:
        model = Book
        fields = ["title"]

Và chế độ xem tôi đang sử dụng là:

from django.shortcuts import render_to_response, redirect, get_object_or_404
from django.template import RequestContext
from books.models import Book,Author
from books.forms import BookForm, SearchForm
from users.models import User

def search_book(request):
    if request.method == "POST":
        form = SearchForm(request.POST)
        if form.is_valid():
            form = SearchForm(request.POST)
            stitle = form.cleaned_data['title']
            sauthor = form.cleaned_data['author']
            scategory = form.cleaned_data['category']
    else:
        form = SearchForm()
    return render_to_response("books/create.html", {
        "form": form,
    }, context_instance=RequestContext(request))

Biểu mẫu hiển thị tốt, nhưng khi tôi gửi nó, tôi gặp lỗi: 'SearchForm' object has no attribute 'cleaned_data'

Tôi không chắc chuyện gì đang xảy ra, ai đó có thể giúp tôi không? Cảm ơn!


8
Tại sao lại gọi form = SearchForm(request.POST)hai lần?
hughdbrown

@SafwanSamsudeen Nhận xét của tôi nói điều tương tự như câu trả lời đã được chấp nhận là đúng 10 năm trước. Vấn đề thực sự là mã không nên gọi SearchForm lần thứ hai.
hughdbrown

Câu trả lời:


178

Vì một số lý do, bạn đang khởi tạo lại biểu mẫu sau khi kiểm tra is_valid(). Các biểu mẫu chỉ nhận được một cleaned_datathuộc tính khi is_valid()đã được gọi, và bạn chưa gọi nó trong trường hợp thứ hai mới này.

Chỉ cần loại bỏ thứ hai form = SearchForm(request.POST)và tất cả sẽ ổn.


7

Tôi sẽ viết mã như thế này:

def search_book(request):
    form = SearchForm(request.POST or None)
    if request.method == "POST" and form.is_valid():
        stitle = form.cleaned_data['title']
        sauthor = form.cleaned_data['author']
        scategory = form.cleaned_data['category']
        return HttpResponseRedirect('/thanks/')
    return render_to_response("books/create.html", {
        "form": form,
    }, context_instance=RequestContext(request))

Khá giống tài liệu hướng dẫn .


Chà, điều đó hiệu quả! Vị trí định nghĩa của biểu mẫu có tạo ra sự khác biệt nhiều không?
Joseph

Tôi không biết vấn đề của bạn là gì, nhưng tôi nghĩ rằng việc gọi SearchForm(request.POST)hai lần là không cần thiết. Phần còn lại chỉ là trang trí cửa sổ: Tôi tình cờ thích cách này để gấp các đối số xây dựng Biểu mẫu để bạn chỉ cần một lệnh gọi.
hughdbrown

Hoặc chính xác những gì @Daniel Roseman đã nói. Nếu tôi là bạn, tôi sẽ chọn anh ấy làm câu trả lời ưa thích vì anh ấy xác định được nguyên nhân chính xác.
hughdbrown

2

Đôi khi, nếu chúng ta quên

return self.cleaned_data 

trong hàm sạch của biểu mẫu django, chúng tôi sẽ không có bất kỳ dữ liệu nào mặc dù form.is_valid()sẽ trả về True.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.