2009-12-13 37 views

Trả lời

2

Tôi có vấn đề này và tôi đã thực hiện một widget mới:

from django.forms.widgets import Select 
from django.utils.safestring import mark_safe 
class PrepolutatedSelect(Select): 
    def render(self, name, value, attrs=None, choices=()): 
     if value is None: value = '' 
     if value == '': 
      value = int(name.split('-')[1])+1 
     final_attrs = self.build_attrs(attrs, name=name) 
     output = [u'<select%s>' % flatatt(final_attrs)] 
     options = self.render_options(choices, [value]) 
     if options: 
      output.append(options) 
     output.append('</select>') 
     return mark_safe(u'\n'.join(output)) 

lẽ điều này sẽ làm việc cho bạn quá.

+0

Tôi có vấn đề tương tự với OP. Tôi đang cố gắng tạo một biểu mẫu với nhiều biểu mẫu, với mỗi biểu mẫu có tập hợp tùy chọn duy nhất của riêng nó cho một phần tử chọn (tức là "lựa chọn"). Tôi hoàn toàn không thể thấy giải pháp này sẽ giúp ích gì. Tui bỏ lỡ điều gì vậy? – ACPrice

10

Bạn cần sử dụng kỹ thuật được mô tả trong this post để có thể chuyển các tham số. Tín dụng cho tác giả đó cho một bài đăng tuyệt vời. Bạn đạt được điều này trong một số bộ phận:

Một hình thức nó sẽ nhặt thông số bổ sung

Ví dụ từ câu hỏi liên quan:

def __init__(self, *args, **kwargs): 
    someeobject = kwargs.pop('someobject') 
    super(ServiceForm, self).__init__(*args, **kwargs) 
    self.fields["somefield"].queryset = ServiceOption.objects.filter(
                  somem2mrel=someobject) 

Hoặc bạn có thể thay thế mã sau với

self.fields["somefield"].initial = someobject 

Trực tiếp và hoạt động.

Một cà ri hình thức thiết lập khởi động:

formset = formset_factory(Someform, extra=3) 
formset.form = staticmethod(curry(someform, somem2mrel=someobject)) 

Đó giúp bạn để đi qua các tham số hình thức tùy chỉnh. Bây giờ những gì bạn cần là:

Một máy phát điện để có được các thông số ban đầu khác nhau của bạn

Tôi đang sử dụng này:

def ItemGenerator(Item): 
    i = 0 
    while i < len(Item): 
     yield Item[i] 
     i += 1 

Bây giờ, tôi có thể làm điều này:

iterdefs = ItemGenerator(ListofItems) # pass the different parameters 
             # as an object here 
formset.form = staticmethod(curry(someform, somem2mrel=iterdefs.next())) 

Xin chào! Mỗi đánh giá của phương pháp form đang được đánh giá ở các phần đi qua trong tham số được lặp lại. Chúng ta có thể lặp lại những gì chúng ta thích, vì vậy tôi đang sử dụng thực tế đó để lặp qua một tập các đối tượng và chuyển giá trị của mỗi đối tượng vào như một tham số ban đầu khác.

+0

hey! Tôi nghĩ câu trả lời của bạn có thể giải quyết được vấn đề tôi giải quyết trong câu hỏi này http://stackoverflow.com/questions/6123278/same-form-different-variables-how-to-implement. Nhưng tôi thực sự không thực sự hiểu những gì đang xảy ra – pavid

+1

Tôi đã thử sử dụng cách tiếp cận này nhưng không thể có được trình lặp để lặp lại trên mỗi cuộc gọi. Mã của tôi: 'DecorationFileFormSet.form = staticmethod (curry (DecorationFileForm, filetype = counter.next()))' tạo các biểu mẫu trong đó thuộc tính filetype là 1 mỗi lần. truy cập là một thể hiện của 'itertools.count (1)' –

+0

Bất cứ ai cũng có giải pháp? Các máy phát điện không hoạt động (không lặp lại ở tất cả) cho tôi là tốt. – wgx731

2

Xây dựng dựa trên câu trả lời của Antony Vennard, tôi không chắc chắn phiên bản python/django anh ấy đang sử dụng nhưng tôi không thể làm cho trình tạo hoạt động trong phương thức cà ri. Tôi hiện đang trên python2.7.3 và django1.5.1. Thay vì sử dụng Trình tạo tùy chỉnh, tôi đã kết thúc bằng cách sử dụng một built-in iter() trên danh sách các thứ để tạo một trình lặp và chuyển bản thân trình vòng lặp trong phương thức cà ri và gọi next() trên nó trong Form__init__().Đây là giải pháp của tôi:

# Build the Formset: 
my_iterator = iter(my_list_of_things) # Each list item will correspond to a form. 
Formset = formset_factory(MyForm, extra=len(my_list_of_things)) 
Formset.form = staticmethod(curry(MyForm, item_iterator=my_iterator)) 

Và theo hình thức:

# forms.py 
class MyForm(forms.Form): 
    def __init__(self, *args, **kwargs): 
     # Calling next() on the iterator/generator here: 
     list_item = kwargs.pop('item_iterator').next() 

     # Now you can assign whatever you passed in to an attribute 
     # on one of the form elements. 
     self.fields['my_field'].initial = list_item 

Một số điều quan trọng tôi thấy được rằng bạn cần phải hoặc chỉ định một giá trị 'phụ' trong formset_factory hoặc sử dụng initial kwarg trên formset để chỉ định một danh sách tương ứng với danh sách bạn chuyển tới trình vòng lặp (Trong ví dụ trên, tôi chuyển len() của danh sách my_list_of_things sang 'extra' kwarg tới formset_factory). Điều này là cần thiết để thực sự tạo một số biểu mẫu trong bộ định dạng.

33

Nếu bạn mắc lỗi tương tự như tôi, bạn đã nhầm lẫn một chút tài liệu.

Khi tôi lần đầu tiên nhìn thấy ví dụ này ...

formset = ArticleFormSet(initial=[ 
{'title': 'Django is now open source', 
    'pub_date': datetime.date.today(),} 
]) 

Tôi cho rằng mỗi hình thức được đưa ra cùng một tập hợp dữ liệu ban đầu dựa trên một cuốn từ điển.

Tuy nhiên, nếu bạn nhìn kỹ, bạn sẽ thấy rằng bộ định dạng thực sự đang được chuyển một danh sách từ điển.

Để đặt các giá trị ban đầu khác nhau cho mỗi biểu mẫu trong một bộ định dạng, bạn chỉ cần chuyển danh sách các từ điển có chứa dữ liệu khác.

Formset = formset_factory(SomeForm, extra=len(some_objects) 
some_formset = FormSet(initial=[{'id': 'x.id'} for x in some_objects]) 
+2

Điều này có vẻ là cách đơn giản nhất để làm điều này, và cách Django mặc định để làm điều đó, và xác định chính xác quan điểm sai lầm mà OP có. Nên là câu trả lời hàng đầu. – ACPrice

+1

Lưu ý rằng điều này sẽ làm cho 'ArticleFormSet' thành [dạng không liên kết] (https://docs.djangoproject.com/en/1.10/topics/forms/#bound-and-unbound-form-instances), vì các giá trị ban đầu sẽ ghi đè lên các giá trị được trả về từ bộ truy vấn Article. –

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