根据 views.py 中的条件删除 modelForms 字段

如果我们有一个模型如下,

from django.db import models
from django.contrib.auth.models import User

class UserModuleProfile(models.Model):
    user = models.OneToOneField(User)
    expired = models.DateTimeField()
    admin = models.BooleanField(default=False)
    employee_id = models.CharField(max_length=50)
    organisation_name = models.ForeignKey('Organizations', on_delete=models.PROTECT)
    country = models.CharField(max_length=100)
    position = models.CharField(max_length=100)

    def __str__(self):
        return self.user

以及使用此模型的模型形式如下,

from .models import UserModuleProfile, from django.contrib.auth.models import User
from django import forms

class UserProfileForm(forms.ModelForm):
    admin = forms.BooleanField(label="Make this User Admin",widget=forms.CheckboxInput(),required=False)
    employee_id = forms.CharField(label="Employee Id ")
    organisation_name = forms.ModelChoiceField(label='Organisation Name',required=True,queryset=Organizations.objects.all(),empty_label="Select an Organization")
    country = forms.CharField(label="Country")
    position = forms.CharField(label="Position")

    class Meta:
        model = UserModuleProfile
        fields = ('admin','employee_id','organisation_name','country','position',)

    def __init__(self, *args, **kwargs):
        admin_check = kwargs.pop('admin_check', False)
        super(UserProfileForm, self).__init__(*args, **kwargs)
        if not admin_check:
            del self.fields['admin']

请注意,在表单的 Meta 类下面,我添加了一个 init 函数,我们可以在从 views.py 初始化表单时使用它来删除表单字段(或其他一些操作)。我稍后会解释。

因此,此表单可用于用户注册目的,我们希望在表单的 Meta 类中定义所有字段。但是,如果我们想在编辑用户时使用相同的表单,但是当我们这样做时,我们不想显示表单的管理字段呢?

当我们根据某些逻辑初始化表单并从后端删除 admin 字段时,我们可以简单地发送一个额外的参数。

def edit_profile(request,user_id):
    context = RequestContext(request)
    user = get_object_or_404(User, id=user_id)
    profile = get_object_or_404(UserModuleProfile, user_id=user_id)
    admin_check = False
    if request.user.is_superuser:
        admin_check = True
    # If it's a HTTP POST, we're interested in processing form data.
    if request.method == 'POST':
        # Attempt to grab information from the raw form information.
        profile_form = UserProfileForm(data=request.POST,instance=profile,admin_check=admin_check)
        # If the form is valid...
        if profile_form.is_valid():
            form_bool = request.POST.get("admin", "xxx")
            if form_bool == "xxx":
                form_bool_value = False
            else:
                form_bool_value = True
            profile = profile_form.save(commit=False)
            profile.user = user
            profile.admin = form_bool_value
            profile.save()
            edited = True
        else:
            print profile_form.errors

    # Not a HTTP POST, so we render our form using ModelForm instance.
    # These forms will be blank, ready for user input.
    else:
        profile_form = UserProfileForm(instance = profile,admin_check=admin_check)

    return render_to_response(
            'usermodule/edit_user.html',
            {'id':user_id, 'profile_form': profile_form, 'edited': edited, 'user':user},
            context)

正如你所看到的,我在这里展示了一个使用我们之前创建的表单的简单编辑示例。请注意,当我初始化表单时,我传递了一个额外的 admin_check 变量,其中包含 TrueFalse

profile_form = UserProfileForm(instance = profile,admin_check=admin_check)

现在如果你注意到我们之前写过的表单,你可以看到在 init 中我们尝试捕获我们从此处传递的 admin_check 参数。如果值为 False,我们只需从表单中删除 admin 字段并使用它。由于这是一个模型表单,管理字段在模型中不能为 null,我们只需检查表单帖子中是否有表单帖子中的 admin 字段,如果不是,我们将在视图代码中的视图代码中将其设置为 False

form_bool = request.POST.get("admin", "xxx")
if form_bool == "xxx":
    form_bool_value = False
else:
    form_bool_value = True