根據 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