2010-03-01 50 views
8

Tôi đang sử dụng nhà máy sản xuất biểu mẫu nội tuyến của django. Để sử dụng ví dụ trong tài liệu,Giới hạn inlineformset_factory của Django chỉ tạo đối tượng mới

author = Author.objects.get(pk=1) 
BookFormSet = inlineformset_factory(Author, Book) 
formset = BookFormSet(request.POST, instance=author) 

sẽ tạo một bộ định dạng nội tuyến để chỉnh sửa sách của một tác giả cụ thể.

Tôi muốn tạo một bộ định dạng chỉ cho phép người dùng thêm sách mới của tác giả đó, không chỉnh sửa sách hiện có. Có một cách đơn giản để sử dụng inlineformset_factory để làm điều này?

Trả lời

6

inlineformset_factory lấy kwarg định dạng, mặc định là BaseInlineFormSet. BaseInlineFormSet lớp con BaseModelFormSet, định nghĩa phương thức get_queryset. Nếu bạn tạo một lớp con BaseInlineFormSet và ghi đè get_queryset để trả về EmptyQuerySet(), bạn sẽ nhận được những gì bạn đang theo sau. Trong ví dụ trên, nó sẽ trông như sau:

from django.db.models.query import EmptyQuerySet 
from django.forms.models import BaseInlineFormSet 

class BaseInlineAddOnlyFormSet(BaseInlineFormSet): 
    def get_queryset(self): 
     return EmptyQuerySet() 

author = Author.objects.get(pk=1) 
BookFormSet = inlineformset_factory(Author, Book, formset=BaseInlineAddOnlyFormSet) 
formset = BookFormSet(request.POST, instance=author) 
+1

[Các tài liệu] (https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#changing-the- queryset) xuất hiện để nói rằng cách ưa thích để đặt queryset là ghi đè '__init__' sau khi gọi tới super. Nhưng điều đó không hiệu quả với tôi. Phương thức của bạn, cũng như thiết lập 'queryset' của kwarg trước khi gọi tới '__init__' của siêu. Cảm ơn. –

0

Thực ra câu trả lời được đưa ra trong documentation. Chỉ cần không đưa ra bất kỳ ví dụ nào cho FormSet. Từ doc:

>>> from django.forms.models import inlineformset_factory 
>>> BookFormSet = inlineformset_factory(Author, Book) 
>>> author = Author.objects.get(name=u'Mike Royko') 
>>> formset = BookFormSet() # This will create an empty form with your model fields 

Sau đó bạn có thể tạo điểm như sau:

if request.method == "POST": 
    formset = BookFormSet(request.POST, request.FILES) 
    if formset.is_valid(): 
     formset.save() 
else: 
    formset = BookFormSet() 
return render_to_response("add_book.html", { 
    "formset": formset, 

Hy vọng nó giúp.

+0

Điều này không hiệu quả đối với tôi; nó vẫn populates các formset với tất cả 'Book's. django 1.4. –

1

Dựa trên Jeremy Lewis và nếu bạn không muốn phân lớp BaseInlineFormSet, bạn chỉ có thể cung cấp tham số queryset trống cho BookFormSet của mình.

Xem mẫu giả (chưa được kiểm tra) Django 1,6 mã:

BookFormSet = inlineformset_factory(parent=Author, model=Book) 
if request.method == "POST": 
    formset = BookFormSet(request.POST, request.FILES, instance=author) 
    if formset.is_valid(): 
     formset.save() 
else: 
    queryset = Book.objects.none() # does not allow to edit books 
    formset = BookFormSet(instance=project, initial=initial, queryset=queryset) 
return render(request, "add_book.html", { "formset": formset, }) 
+0

inlineformset_factory giờ yêu cầu thông số 'trường' được chỉ định rõ ràng. Chỉ cần cập nhật. – Rexford

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