Django:带条件的ModelForm

Buk*_*uky 6 django django-templates django-models django-forms django-views

我正在尝试创建一个表单变量。默认播放器的级别为 0,他可以更改名称。以后到了1级,就可以改名字和头像了。当他3级时,他可以改变名字、头像和工作。等等...

模型.py:

class Player(models.Model):
    level = models.SmallIntegerField(default=0) 
    name = models.CharField(max_length=50)
    avatar = models.URLField(default='http://default-picture.com/01.png')
    job =  models.TextField(null=True)
Run Code Online (Sandbox Code Playgroud)

Formrs.py:

class ProfileForm(forms.ModelForm):

class Meta:
    model = Player
    fields = ['name', 'avatar', 'job']
    widgets = {
        'name': forms.TextInput(),
        'avatar': forms.TextInput(),
        'job': forms.Textarea(),
    }
Run Code Online (Sandbox Code Playgroud)

视图.py:

def game(request, id):
    user = get_object_or_404(Player, id=id)
    if request.method == 'POST':
        form = ProfileForm(request.POST, instance=user)
        if form.is_valid():
            form.save()
            return HttpResponse('Success')
    else:
        form = ProfileForm(instance=user)
    return render(request, "page/template.html",
            {'form': form})
Run Code Online (Sandbox Code Playgroud)

模板.html:

{{ form }}
Run Code Online (Sandbox Code Playgroud)

在将表单发送到渲染引擎之前,可以为表单的渲染添加条件吗?或者我需要在我的模板中使用条件来完成?

我只是何时允许实例化对象在这些参数之一方面具有更多或更少的可能性(在示例中是玩家的级​​别)。

Mar*_*aum 8

您可以覆盖表单的__init__方法以有条件地删除或禁用字段:

class ProfileForm(forms.ModelForm):
    ...
    def __init__(self, *args, **kwargs):
        super(ProfileForm, self).__init__(*args, **kwargs)
        if self.instance and self.instance.level < 3:
            self.fields['job'].disabled = True # still displays the field in the template
            # del self.fields['job'] # removes field from form and template
        if self.instance and self.instance.level < 1:
            self.fields['avatar'].disabled = True
Run Code Online (Sandbox Code Playgroud)