2017-11-28 8 views
0

클래스의 exercise_type 필드에 따라 ModelForm의 메타 클래스 위젯을 동적으로 생성하고 싶습니다. 어떻게 값을 얻을 수 있습니까?Django : ModelForm의 필드 위젯을 동적으로 업데이트하십시오.

class ExerciseAdminForm(ModelForm): 

    class Meta: 
     model = Exercise 
     fields = '__all__' 
     widgets = { 
      'starter_code': _make_language_mode(exercise_type=Exercise.exercise_type) 
     } 

나는 excercise_object을 얻을하는 방법을 모르겠어요.


기본적으로 내가 입력 필드에 대한 CodeMirrorSkulpt 지원을 사용, 관리 인터페이스의 기본 양식을 오버라이드 (override) 할 필요가있다.

class ExerciseAdminForm(ModelForm): 

    def __init__(self, *args, **kwargs): 
     super(ExerciseAdminForm, self).__init__(*args, **kwargs) 
     print("DEBUG: len(kwargs)=",len(kwargs)) 
     initial_dict = kwargs['initial'] 
     print("DEBUG: len(initial_dict)=",len(initial_dict)) 
     self.fields['starter_code'].widget = _make_language_mode(exercise_type=excercise_object.exercise_type) 


    class Meta: 
     model = Exercise 
     fields = '__all__' 
     widgets = { 
      'preamble': _make_markdown_mode() 
     } 

내 디버그 메시지가 보여

("디버그 : LEN (kwargs로) = '1)

('DEBUG : LEN (initial_dict) = '0)

내 함수는 파이썬 2.7 라이브러리 사이트 패키지에서 호출되는 :

/root/.virtualenvs/codebench/local/lib/python2.7/site-packages/django/contrib/admin/options.py 라인 1481에서

:

form = ModelForm(initial=initial) 

에서 changeform_view 기능 :

@csrf_protect_m 
@transaction.atomic 
def changeform_view(self, request, object_id=None, form_url='', extra_context=None): 

to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR)) 
if to_field and not self.to_field_allowed(request, to_field): 
    raise DisallowedModelAdminToField("The field %s cannot be referenced." % to_field) 

model = self.model 
opts = model._meta 
add = object_id is None 

if add: 
    if not self.has_add_permission(request): 
     raise PermissionDenied 
    obj = None 

else: 
    obj = self.get_object(request, unquote(object_id), to_field) 

    if not self.has_change_permission(request, obj): 
     raise PermissionDenied 

    if obj is None: 
     raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % { 
      'name': force_text(opts.verbose_name), 'key': escape(object_id)}) 

    if request.method == 'POST' and "_saveasnew" in request.POST: 
     return self.add_view(request, form_url=reverse('admin:%s_%s_add' % (
      opts.app_label, opts.model_name), 
      current_app=self.admin_site.name)) 

ModelForm = self.get_form(request, obj) 
if request.method == 'POST': 
    form = ModelForm(request.POST, request.FILES, instance=obj) 
    if form.is_valid(): 
     form_validated = True 
     new_object = self.save_form(request, form, change=not add) 
    else: 
     form_validated = False 
     new_object = form.instance 
    formsets, inline_instances = self._create_formsets(request, new_object, change=not add) 
    if all_valid(formsets) and form_validated: 
     self.save_model(request, new_object, form, not add) 
     self.save_related(request, form, formsets, not add) 
     if add: 
      self.log_addition(request, new_object) 
      return self.response_add(request, new_object) 
     else: 
      change_message = self.construct_change_message(request, form, formsets) 
      self.log_change(request, new_object, change_message) 
      return self.response_change(request, new_object) 
else: 
    if add: 
     initial = self.get_changeform_initial_data(request) 
     form = ModelForm(initial=initial) 
     formsets, inline_instances = self._create_formsets(request, self.model(), change=False) 
    else: 
     form = ModelForm(instance=obj) 
     formsets, inline_instances = self._create_formsets(request, obj, change=True) 

adminForm = helpers.AdminForm(
    form, 
    list(self.get_fieldsets(request, obj)), 
    self.get_prepopulated_fields(request, obj), 
    self.get_readonly_fields(request, obj), 
    model_admin=self) 
media = self.media + adminForm.media 

inline_formsets = self.get_inline_formsets(request, formsets, inline_instances, obj) 
for inline_formset in inline_formsets: 
    media = media + inline_formset.media 

context = dict(self.admin_site.each_context(request), 
    title=(_('Add %s') if add else _('Change %s')) % force_text(opts.verbose_name), 
    adminform=adminForm, 
    object_id=object_id, 
    original=obj, 
    is_popup=(IS_POPUP_VAR in request.POST or 
       IS_POPUP_VAR in request.GET), 
    to_field=to_field, 
    media=media, 
    inline_admin_formsets=inline_formsets, 
    errors=helpers.AdminErrorList(form, formsets), 
    preserved_filters=self.get_preserved_filters(request), 
) 

context.update(extra_context or {}) 

return self.render_change_form(request, context, add=add, change=not add, obj=obj, form_url=form_url) 
+0

전달할 '초기'인수는 무엇입니까? 내가 답변 – rajkris

+0

에있는 운동 객체로 가정합니다. 장고 기본 라이브러리는 python2.7/site-packages/django/contrib/admin/options.py에서 호출합니다. 그 부분은 확실하지 않습니다. – Miranda

+0

실제 요구 사항을 자세히 설명해 주시겠습니까? change_form_view를 게시 할 수 있습니까? – rajkris

답변

0

아마 당신은이 작업을 수행 할 수있는 초기화 기능을 무시할 수 있을까? 운동 인스턴스를 키워드 arg로 폼에 전달하십시오. 양식과 함께 운동 객체를 전달하면 _make_language_mode가 위젯을 반환한다고 가정합니다.

def __init__(self, *args, **kwargs): 
    excercise_object = kwargs["excercise"] 
    self.fields['starter_code'].widget = _make_language_mode(exercise_type=excercise_object.exercise_type)