Django:我可以给一个表格一个参数来用于不同的情况吗?

时间:2013-03-07 12:37:45

标签: django django-forms django-views

我是Django的新用户,我使用一次表格两次用户帐户(用户名,密码)。第一个用户是必需的,第二个用户是可选的。

问题是,复选框也按要求显示。我可以为视图提供参数以避免第一个用户使用该复选框并将其显示给第二个用户吗?我想做一个像

这样的案子

这可能吗?我不想写同一个字段的两个不同的类只是因为一个不同的字段。

我的代码:

views.py

if request.method == "POST":
    admin_form = MysqlDatabaseForm_user(request.POST or None, given_argument='admin')
    user_form = MysqlDatabaseForm_user(request.POST or None, given_argument='extra_user')

    if admin_form.is_valid():
            #do something
    if user_form.is_valid():
            #do something


else:
    admin_form = MysqlDatabaseForm_user()
    user_form = MysqlDatabaseForm_user()

return TemplateResponse(request, "services/database/add_service_database.html", {'admin_form': admin_form,
                                                                                 'user_form': user_form},)

forms.py

class MysqlDatabaseForm_user(forms.ModelForm):
class Meta:
    model = MysqlUser

def __init__(self, *args, **kwargs):
    given_argument = kwargs.pop('given_argument', None)
    super(MysqlDatabaseForm_user, self).__init__(*args, **kwargs)

    if given_argument == 'extra_user':
        self.fields['extra_user'] = forms.BooleanField(required=False)
    else:
        self.fields[given_argument] = forms.BooleanField(required=False)

else-case用于筛选,“given_argument”中的内容。它似乎是空的

3 个答案:

答案 0 :(得分:1)

#forms.py
class UserForm(forms.ModelForm):
    username = forms.CharField(max_length=255)

    def __init__(self, *args, **kwargs):
        given_argument = kwargs.pop('given_argument', None)
        super(UserForm, self).__init__(*args, **kwargs)

        if given_argument:
            if given_argument == 'extra_user':
                key = 'extra_user'
            else:
                key = given_argument.lower()
            self.fields[key] = forms.BooleanField(required=False)

#views.py
def your_view(request):
    user_form = UserForm(request.POST or None, given_argument='extra_user',
        prefix='user')
    admin_form = UserForm(request.POST, given_argument='admin', prefix='admin')
    ...

#template.html
<form action="." method="post" enctype="[the enctype you need]">
    <ol>
        <li>User Form</li>
        {{ user_form.as_ul }}
    </ol>

    <ol>
        <li>Admin Form</li>
        {{ admin_form.as_ul }}
    </ol>

    <input type="submit" value="Submit" />
</form>

只需覆盖__init__,然后在课堂上调用**kwargs之前从super()中弹出额外的参数。这将允许您传入参数,将其从表单类通常期望的**kwargs中删除,然后传递剩余的**kwargs

如果您要从传入的参数中分配字段的键,则需要注意传入的值。没有特殊字符,空格等。

如果表单是GET请求,则不需要单独的条件来实例化表单 - 这是request.POST or None在传递给表单类构造函数时完成的。

您也不需要两个单独的模型表单类。您将键参数传递给字段构造函数,因此您可以使用相同的表单类,只需传入可选参数即可。您会注意到我已经在表单中添加了prefix参数,以防止命名字段之间的冲突。

答案 1 :(得分:1)

class MysqlDatabaseForm_user(forms.ModelForm):
    class Meta:
        model = MysqlUser

    def __init__(self, given_argument, *args, **kwargs):
        super(MysqlDatabaseForm_user, self).__init__(*args, **kwargs)

        if given_argument == 'extra_user':
            self.fields['extra_user'] = forms.BooleanField(required=False)



def view(request):
    if request.method == 'POST':
        admin_form = MysqlDatabaseForm_user(request.POST, given_argument='admin') 
        user_form = MysqlDatabaseForm_user(request.POST, given_argument='extra_user')
        ...........
    else:
        admin_form = MysqlDatabaseForm_user(given_argument='admin') 
        user_form = MysqlDatabaseForm_user(given_argument='extra_user')

    return render(request, 'page.html', {
        'admin_form': admin_form,
        'user_form': user_form,
    })

答案 2 :(得分:0)

使用modelform_factory将代码角色作为自己的形式。 (通过这样一个简单的例子,您也可以手动编写代码。请参阅下面的Catherine示例,了解手动编码的一个很好的例子。)

怎么样:

from django.forms.models import modelform_factory
form_fields = ['extra_user'] if given_argument == 'extra_user' else []
user_form = modelform_factory(Model, form=MysqlDatabaseForm_user, fields=form_fields)

user_form.is_valid()应该有效,因为extra_user字段为required=False

Django允许您从Model及其ModelForm对应项派生自定义表单。您甚至可以创建不立即验证的表单,但可以使用它来创建在进一步活动后保存的Model对象。具体来说,你可以......

if request.Post:
  form = user_form(request.POST)
  model_object = form.save(commit=False) # now you have an model instance, and no longer need the form
  model_object = process_object(model_object)
  model_object.save()

这两个工具modelform_factory以及form.save(commit=False)的功能通常可以避免重新定义标准方法,例如__init__save。我经常发现当我认为我需要修改这些方法时,我遗漏了Django自然构建的一些功能。