详解Django的 get_initial() 函数:获取表单的初始值

  • Post category:Python

get_initial()是Django视图类中的一个函数,用于获取表单初始值。该函数在呈现表单前被调用,旨在通过程序逻辑或基于其他值的计算来计算并提供表单的初始化值。以下是详细的使用说明和示例:

作用

get_initial()函数用于在前端呈现表单前获取表单的初始化值。经常用于从数据库或其他动态数据源加载默认值。尽管表单可以在前端使用js来为表单的字段提供默认值,但是使用 get_initial() 函数可以在后端计算初始值,这样可以提高表单安全性,防止前端数据篡改等安全问题。

请注意,如果表单没有定义 initial 属性, get_initial() 函数将被禁用。

使用方法

在视图类中,添加 get_initial() 函数来获取表单的初始化值并返回一个字典对象。字典的键必须与表单中的字段名称相对应。

以下是一个示例:

from django import forms
from django.views.generic.edit import CreateView

from .models import BlogPost


class BlogPostForm(forms.ModelForm):
    class Meta:
        model = BlogPost
        fields = ('title', 'body', 'tags',)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['tags'].help_text = 'Separate tags with commas.'

class BlogPostCreateView(CreateView):
    model = BlogPost
    form_class = BlogPostForm
    template_name = 'blogpost_form.html'
    success_url = '/'

    def get_initial(self):
        initial = super().get_initial()
        initial['title'] = "A wonderful blog post"
        initial['body'] = "Once upon a time..."
        return initial

在上面的代码示例中,get_initial() 函数被重载以返回一个字典对象。在这个例子中,我们为 titlebody 手动提供初始值(即“A wonderful blog post”和“Once upon a time…”)。该视图将返回一个表单,该表单将自动填充这些字段。

示例:

假设我们的网站是一个博客网站,并且我们需要定义一个创建博客文章的表单。这个表单需要一个文本区域用于输入文章的内容,并且还需要一个下拉列表,用于选择文章的类别:

from django import forms
from django.views.generic.edit import CreateView

from .models import BlogPost, Category


class BlogPostForm(forms.ModelForm):
    content = forms.CharField(widget=forms.Textarea)
    category = forms.ModelChoiceField(queryset=Category.objects.all())

    class Meta:
        model = BlogPost
        fields = ('title', 'content', 'category',)


class BlogPostCreateView(CreateView):
    model = BlogPost
    form_class = BlogPostForm
    template_name = 'blogpost_form.html'
    success_url = '/'

    def get_initial(self):
        initial = super().get_initial()
        initial['category'] = Category.objects.get(name='Uncategorized')
        return initial

在上面的示例中,我们定义了一个 BlogPostForm 类来表示博客文章的表单,并在 BlogPostCreateView 类中使用该表单。在 get_initial() 函数中,我们指定了一个默认值,即“未分类”。这个默认值将会被我们的下拉列表所选中。如果有一个新的类别被添加到数据库中,该默认值将在下次运行视图时自动更新,因为我们使用的是动态数据源的查询。

另一个示例是,在 get_initial() 函数中使用程序逻辑来动态计算表单的初始值:

class BlogPostCreateView(CreateView):
    model = BlogPost
    form_class = BlogPostForm
    template_name = 'blogpost_form.html'
    success_url = '/'

    def get_initial(self):
        initial = super().get_initial()
        if self.request.user.is_authenticated:
            initial['author'] = self.request.user
        return initial

在上面的示例中,我们在 get_initial() 函数中使用 request 对象来获取当前用户的身份(如果已经登录),并将其指定为表单的初始值。由于我们的视图类是一个基于类的视图,所以我们可以方便地访问 request 对象并计算初始化值,并将其传递给表单。