详解Django的 get_form() 函数:获取视图所使用的表单实例

  • Post category:Python

Django的get_form()函数是 ModelAdmin 类中的一个方法,用于获取指定的表单类或动态生成一个表单类,并返回该表单类的实例。在 Django 中,表单用于收集和处理用户提交的数据,get_form()则为我们提供了轻松自定义表单类的方式,从而在后台管理中实现更加灵活的数据验证、处理、展示等功能。

get_form()的基本用法为:

class MyModelAdmin(admin.ModelAdmin):
    # 配置其他 ModelAdmin 生命周期的方法(比如 display、fieldsets、list_editable)

    form = MyFormClass 
    # 可选;指定表单使用的 Form 类。在指定该类时,get_form() 方法将不再更新其中的表单字段。

    def get_form(self, request, obj=None, **kwargs):
        # 表单类配置逻辑
        return some_form(instance=obj, **kwargs)  # 返回表单实例

其中,obj 参数为当前查询的对象实例,**kwargs 一般包含许多表单的其他配置项,比如 widgets、include、exclude、fields 等。下面针对 get_form() 的使用方法和实例进行详细讲解。

1. 使用场景

get_form() 可以应用于 ModelAdmin 类中的各个功能及扩展,比如:

  • 动态生成表单字段;
  • 自定义表单类,添加或移除字段等;
  • 指定特定的表单类;
  • 指定前端页面渲染模板等。

2. 示例一:生成动态的表单字段

在一个基于表单的应用中,不同页面对应的表单字段数量和类型可能完全不同。因此,我们需要动态生成表单类,并在其中添加不同的表单字段。

class AccountAdmin(admin.ModelAdmin):
    # 配置其他 ModelAdmin 生命周期的方法(比如 display、fieldsets、list_editable)

    def get_form(self, request, obj=None, **kwargs):
        form_cls = AccountForm

        # 根据上下文和业务规则动态生成该 Form 类的字段
        if obj is not None and obj.status == 'deactivated':
            form_cls = AccountsReactivateForm
        else:
            form_cls = AccountsForm

        return form_cls(**kwargs)

在此示例中,get_form() 方法根据页面上的内容与上下文动态生成表单类,从而实现了不同的表单字段生成。此外,如果 obj 对应的对象状态为 deactivated,则使用 AccountsReactivateForm 表单类,否则使用 AccountsForm。

3. 示例二:自定义表单,添加或移除字段等

为了控制表单中的字段排列及图标显示等更多细节,我们可以添加表单类的字段,或移除原有字段。

class YourModelAdmin(admin.ModelAdmin):
    # 配置其他 ModelAdmin 生命周期的方法(比如 display、fieldsets、list_editable)

    def get_form(self, request, obj=None, **kwargs):
        form_cls = super().get_form(request, obj=obj, **kwargs)
        # 如果表单中存在 comment 字段,就修改 widget 的 options 长度限制
        if 'comment' in form_cls.base_fields:
            form_cls.base_fields['comment'].widget.attrs['maxlength'] = 400

        # 添加自定义字段
        form_cls.base_fields['custom_field'] = models.IntegerField()

        # 移除原有的字段
        if 'author' in form_cls.base_fields:
            del form_cls.base_fields['author']

        return form_cls

在上面的示例中,我们首先使用 super() 获取到原有的表单类(即 Django 自带生成的 ModelForm 类),然后根据需要在表单类中动态增加或删除字段。

4. 更多使用技巧

除了上述示例,我们还可以根据具体的业务逻辑或前端展示效果,使用 get_form() 函数来实现更加复杂的功能,包括:

  • 实现表单分页;
  • 添加样式和事件;
  • 修改表单提交地址;
  • 处理 or override 表单数据。

总之,get_form() 是表单开发和后台管理功能必不可少的重要方法之一。通过熟练应用和深入了解,我们可以更好地完成各种数据管理和显示等任务。