【问题标题】:Passing a Django Form Class variable to the nested class Meta, how?将 Django Form Class 变量传递给嵌套类 Meta,如何?
【发布时间】:2012-01-22 21:21:16
【问题描述】:

在那里。我现在比什么都烦。正如预期的那样,下面的代码完全可以工作。基本上,它是一个 ModelForm,它动态地将其模型基于在 url 中接收到的字符串,或者基于实例的类(如果提供的话)。

我的问题是,是否可以通过传递 model_name 变量将其抽象到另一个模块 forms.py 中。我可以将 model_name 传递给表单 Class 没有问题,但之后我不知道如何将它传递给 Meta。有什么简单的方法可以做到这一点?如果不是这样,它会做,但它会使我的视图代码堆更整洁。

@user_passes_test(lambda u: u.is_staff, login_url="%slogin/" % NINJA_ADMIN_URL_PREFIX)
def content_form(request, model_name=None, edit=False, call_name=''):
    if edit:
        content = Content.objects.get(call_name=call_name)
        model_name = content.fields.__class__.__name__

    class ContentForm(forms.ModelForm):
        parent = ModelTextField(queryset=Content.objects.all(), widget=JQueryAutocomplete(
                        source_url='%sjson/call_names.json' % NINJA_ADMIN_URL_PREFIX, jquery_opts = {'minLength': 2},
                        override_label='item.fields.call_name', override_value='item.fields.call_name'),
                        required=False)

        class Meta():
            model = get_ninja_type(model_name)
            widgets = {
                    'ninja_type': forms.widgets.HiddenInput(),
                }

        def clean_parent(self):
            call_name = self.cleaned_data['parent']
            if call_name:
                try:
                    parent = Content.objects.get(call_name=call_name)
                except Content.DoesNotExist:
                    raise forms.ValidationError("The call name '%s' doesn't exist. Choose another parent." % call_name)
                return parent
            else:
                return None

    if request.method == 'POST':
        if edit:
            form = ContentForm(request.POST, instance=content.fields)
        else:
            form = ContentForm(request.POST)
        if form.is_valid():
            content = form.save()
            messages.success(request, "Your new content has been saved.")
            return HttpResponseRedirect('%scontent/' % NINJA_ADMIN_URL_PREFIX)

    else:
        if edit:
            form = ContentForm(instance=content.fields)
        else:
            form = ContentForm(initial={'ninja_type': model_name.lower(),
                                    'author': request.user})
    if edit:
        page_title = 'Edit %s' % model_name
    else:
        page_title = 'Create New %s' % model_name

    return render(request, 'ninja/admin/content_form.html', {
                  'form': form,
                  'ninja_type': model_name,
                  'page_title': page_title,
                  'edit': edit,
                  'meta_field_names': NINJA_META_FIELD_NAMES,
                  })

【问题讨论】:

  • 我有一个想法,也许表单可以包装在一个返回类的函数中,然后调用该函数。有机会我会试试的。
  • 是的,返回类的函数可以正常工作。一旦网站允许我发布答案的来源。 (声望太低)

标签: python django django-forms


【解决方案1】:

当我想到它时,答案很明显。返回类的函数工作正常。这是views.py 开头的内容。我认为这可能是最好的方法,或者至少是最简洁的方法。

@user_passes_test(lambda u: u.is_staff, login_url="%slogin/" % NINJA_ADMIN_URL_PREFIX)
def content_form(request, model_name=None, edit=False, call_name=''):
    if edit:
        content = Content.objects.get(call_name=call_name)
        model_name = content.fields.__class__.__name__

    ContentForm = get_content_form(model_name)

    if request.method == 'POST':
        if edit:
            form = ContentForm(request.POST, instance=content.fields)
        else:

这是 forms.py 条目。

def get_content_form(model_name):
    class DynamicContentForm(forms.ModelForm):
        parent = ModelTextField(queryset=Content.objects.all(), widget=JQueryAutocomplete(
                        source_url='%sjson/call_names.json' % NINJA_ADMIN_URL_PREFIX, jquery_opts = {'minLength': 2},
                        override_label='item.fields.call_name', override_value='item.fields.call_name'),
                        required=False)

        class Meta():
            model = get_ninja_type(model_name)
            widgets = {
                    'ninja_type': forms.widgets.HiddenInput(),
                }

        def clean_parent(self):
            call_name = self.cleaned_data['parent']
            if call_name:
                try:
                    parent = Content.objects.get(call_name=call_name)
                except Content.DoesNotExist:
                    raise forms.ValidationError("The call name '%s' doesn't exist. Choose another parent." % call_name)
                return parent
            else:
                return None
    return DynamicContentForm

【讨论】:

    猜你喜欢
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-01
    • 2013-10-17
    • 1970-01-01
    • 2012-12-07
    相关资源
    最近更新 更多