2012-04-05 21 views
5

Chúng tôi đang xây dựng một thuật sĩ bằng cách sử dụng chức năng trình thuật sĩ biểu mẫu mới của Django 1.4.
Tài liệu về điều này rất ngắn gọn và chúng tôi không thể tìm thấy bất kỳ ví dụ nâng cao nào. Chúng tôi đang sử dụng một thuật sĩ bước được đặt tên (cần thiết để hỗ trợ một listview/datagrid chúng tôi sử dụng) và một phụ trợ phiên. Trình hướng dẫn có nghĩa là chỉnh sửa vai trò và quyền liên kết và được xây dựng để cung cấp cả chức năng thêm và chỉnh sửa. Chúng tôi thực hiện việc này bằng cách yêu cầu người dùng ở bước đầu tiên nếu họ muốn thêm hoặc chỉnh sửa.Cần làm rõ về cách sử dụng Django 1.4 Biểu mẫu Wizards, đặc biệt trước khi điền và tiết kiệm

Bước tiếp theo phụ thuộc vào lựa chọn đó; Nếu người dùng muốn chỉnh sửa, có màn hình tìm kiếm, theo sau là listview/datagrid hiển thị kết quả. Sau đó, người dùng có thể chọn một trong các kết quả và chuyển đến màn hình chi tiết, theo sau là trang FilteredSelectMultiple, cho phép anh ta/cô ấy liên kết các quyền đối với vai trò này.

Nếu người dùng muốn thêm vai trò mới, màn hình tìm kiếm và kết quả bị bỏ qua và người dùng chuyển trực tiếp đến màn hình chi tiết, sau đó là màn hình liên kết.
Tất cả đều hoạt động khá tốt, sử dụng một condition_dict trong urls.py, nhưng chúng tôi đang tự hỏi một vài điều về các chức năng chung:

Khi một vai trò tồn tại từ trước cụ thể được chọn, làm thế nào chúng ta có thể lấp đầy chi tiết và màn hình liên kết với dữ liệu tương ứng?

Chúng ta có thể khởi tạo một đối tượng vai trò và truyền nó theo hai dạng, nếu vậy, chúng ta sẽ làm điều đó ở đâu và chúng ta có cần thực hiện điều đó cho mỗi biểu mẫu riêng biệt (có vẻ như trên đầu trang) không?

Khi lưu, thực tế phổ biến là tạo một thể hiện khác của đối tượng vai trò, thêm dữ liệu biểu mẫu vào và lưu, hoặc chúng ta có thể sử dụng lại đối tượng được sử dụng trong biểu mẫu không?

Chúng tôi đã cố gắng quá tải get_form_instance trở lại trường hợp của vai trò, và chúng tôi đã xem xét instance_dict trong các tài liệu, nhưng nó cảm thấy như là cách tiếp cận sai lầm và không có ví dụ để được tìm thấy trên mạng, và chúng tôi thậm chí không chắc chắn chúng được sử dụng để điền trước dữ liệu hoặc thậm chí nếu chúng tôi đang đi đúng hướng. Một cách hợp lý, tôi sẽ nói trong bước chọn một vai trò hiện có, tôi cần phải điền vào các biến thuật sĩ bằng cách sử dụng một thể hiện của đối tượng được chọn, và chúng được hiển thị trong các biểu mẫu. Ở cuối wizard, chúng ta đảo ngược quá trình và lấy tất cả dữ liệu từ các biến-wizard và thêm chúng vào một đối tượng vai trò mới được tạo ra và lưu nó. Lý tưởng nhất là cá thể này sẽ tự xác định nếu nó cần thực hiện một INSERT hoặc một UPDATE, tùy thuộc vào việc khóa promary có được lấp đầy hay không.

Nếu bất kỳ ai cũng có thể cung cấp ví dụ hoặc di chuyển đúng hướng, nó sẽ được đánh giá rất nhiều.

Mã của lớp wizardview trong views.py là dưới đây:

class RolesWizard(NamedUrlSessionWizardView): 

def get_template_names(self): 
    # get template for each step... 
    if self.steps.current == 'choice': 
     return 'clubassistant/wizard_neworeditrole.html' 
    if self.steps.current == 'search': 
     return 'clubassistant/wizard_searchrole.html' 
    if self.steps.current == 'results': 
     return 'clubassistant/wizard_pickrole.html' 
    if self.steps.current == 'details': 
     return 'clubassistant/wizard_detailsrole.html' 
    elif self.steps.current == 'rights': 
     return 'clubassistant/wizard_roles.html' 

def get_context_data(self, form, **kwargs): 
    # get context data to be passed to the respective templates 
    context = super(RolesWizard, self).get_context_data(form=form, **kwargs) 

    # add the listview in the results screen 
    if self.steps.current == 'results': 
     # get search text from previous step 
     cleaned_data = self.get_cleaned_data_for_step('search') 
     table = RolesTable(Roles.objects.filter(
      role_name__contains=cleaned_data['searchrole']) 
     ) 
     RequestConfig(self.request, paginate={ 
      "per_page": 4, 
      }).configure(table) 
     # add the listview with results 
     context.update({'table': table}) 

    # add a role instance based on the chosen primary key 
    if self.steps.current == 'rights': 
     cleaned_data = self.get_cleaned_data_for_step('results') 
     role_id = cleaned_data['role_uuid'] 
     role = get_object_or_404(Roles, pk=role_id) 
     context.update({'role': role}) 

    return context 

def done(self, form_list, **kwargs): 
    # this code is executed when the wizard needs to be completed 

    # combine all forms into a single dictionary 
    wizard = self.get_all_cleaned_data() 

    if wizard.get("neworeditrole")=="add": 
     role = Roles() 
    else: 
     role = get_object_or_404(Roles, pk=wizard.get("role_uuid")) 

    # many-to-many rights/roles 
    role.role_rights_new_style.clear() 
    for each_right in wizard.get('role_rights_new_style'): 
     RightsRoles.objects.create(role=role, right=each_right,) 

    # other properties 
    for field, value in self.get_cleaned_data_for_step('details'): 
     setattr(role, field, value) 

    role.save() 

    # return to first page of wizard... 
    return HttpResponseRedirect('/login/maintenance/roles/wizard/choice/') 

Trả lời

1

Hãy xem nếu tôi có thể giúp đỡ. Tôi đã làm một trình hướng dẫn biểu mẫu cho biết thêm các bước tùy thuộc vào câu trả lời.Tại mỗi bước tôi tiết kiệm mọi hình thức trong một biến phiên giao dịch, như vậy:

def process_step(self, request, form, step): 
    request.session['form_list'] = self.form_list 
    request.session['initial'] = self.initial 

Sau đó, mỗi khi xem được trả lại, tôi nhanh chóng một thuật sĩ hình thức mới với tất cả các dữ liệu theo thời gian:

def dynamic_wizard(request): 
    if not request.session.get('form_list'): 
     form = Wizard([Form1]) 
    else: 
     form = Wizard(request.session.get('form_list'), initial = request.session['initial']) 
    return form(context=RequestContext(request), request=request) 
+0

Đây là django 1.3. – daigorocub

2

Đối với các googlers trong tương lai:

Tôi đã có một số thành công với việc sử dụng get_form() vì nó được gọi trước khi biểu mẫu được hiển thị. Bắt đầu với một vài ModelForms:

class Wizard1(models.ModelForm): 
    class Meta: 
     model = MyModel 
     fields = ('field0', 'model0') 
class Wizard2(models.ModelForm): 
    class Meta: 
     model = MyModel 
     excludes = ('field0', 'model0') 

Sau đó, trong SessionWizardView của bạn:

class MyWizard(SessionWizardView): 
    def get_form(self, step=None, data=None, files=None): 
     form = super(ExtensionCreationWizard, self).get_form(step, data, files) 

     if step is not None and data is not None: 
      # get_form is called for validation by get_cleaned_data_for_step() 
      return form 

     if step == "0": 
      # you can set initial values or tweak fields here 

     elif step == "1": 
      data = self.get_cleaned_data_for_step('0') 
      if data is not None: 
       form.fields['field1'].initial = data.get('field0') 
       form.fields['field2'].widget.attrs['readonly'] = True 
       form.fields['field3'].widget.attrs['disabled'] = True 
       form.fields['model1'].queryset = Model1.objects.filter(name="foo") 

     return form 

Hành động là tất cả trong bước 1. bạn yêu cầu xác nhận dữ liệu từ bước 0 (mà gây nên một cuộc gọi khác đến get_form () cho bước 0, vì vậy hãy cẩn thận) và sau đó bạn có thể truy cập bất kỳ giá trị nào được đặt ở bước 0.

Tôi đã ném một vài ví dụ về cài đặt bạn có thể thay đổi trên các trường. Bạn có thể cập nhật một queryset để giới hạn các giá trị trong một ChoiceField, hoặc tái hiển thị một giá trị một lần nữa nhưng làm cho nó chỉ đọc. Một báo trước tôi nhận thấy ... chỉ đọc không hoạt động trên ChoiceField. Bạn có thể làm cho nó bị vô hiệu hóa, nhưng sau đó giá trị không được lan truyền khi bạn gửi biểu mẫu.

+0

Đây là cách để làm điều đó! – JeffC

+0

hmm, "get_form" phương pháp là kinda không may ở đây theo ý kiến ​​của tôi, vì bất kỳ hình thức công cụ liên quan nên được giữ trong lớp mẫu chính nó. Cách tốt hơn là sử dụng get_form_kwargs để đặt "cờ" và sau đó sử dụng chúng để tùy chỉnh các trường bên trong phương thức init của biểu mẫu. – mariodev

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