详解Django的 get_form_kwargs() 函数:获取表单的关键字参数

  • Post category:Python

get_form_kwargs()是Django框架中的一个函数,它是FormMixin的一个方法。在用于创建表单的视图中,使用该方法可以获得表单的所有初始化参数,这些初始化参数将传递给表单的构造函数。下面我们来详细介绍一下它的作用和使用方法。

作用

在Django框架中,使用FormView(或其子视图)创建创建表单类的实例时,有时需要传入一些额外的附加参数,比如一些用于表单验证或表单初始化的参数。那么这些参数从哪里来呢?这时就可以用get_form_kwargs()方法来获取这些参数。该方法返回一个字典,这个字典包含了传递给表单构造函数的所有附加参数,这样表单就会得到这些参数用于验证或初始化。

具体来说,get_form_kwargs()方法将request.GETrequest.POSTFormView.kwargs合并到一个字典中,然后将这个字典返回。这个字典将传递给表单的构造函数,作为参数来初始化表单对象。

使用方法

get_form_kwargs()方法通常在视图中被重写,从而获得附加参数来传递给表单的构造函数。下面是一个使用get_form_kwargs()方法的示例:

from django.views.generic.edit import FormView
from myapp.forms import ContactForm

class ContactView(FormView):
    template_name = 'contact.html'
    form_class = ContactForm
    success_url = '/thanks/'

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['subject'] = self.kwargs['subject']
        return kwargs

    def form_valid(self, form):
        form.send_email()
        return super().form_valid(form)

在这个示例中,我们重新实现了get_form_kwargs()方法。该方法调用父类的同名方法来获取视图对象FormView的默认行为。然后我们添加了一个键值对到返回的字典kwargs中。这里我们向kwargs中添加了一个主题参数。最后返回kwargs字典。

我们还可以使用更多图片来传递参数。比如,我们可以使用查询参数:

class AddressBookView(FormView):
    template_name = 'addressbook.html'
    form_class = ContactForm
    success_url = '/thanks/'

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        if 'selected' in self.request.GET:
            kwargs['initial'] = {'email': self.request.GET['selected']}
        return kwargs

在这个示例中,我们检查了请求是否包含一个查询参数selected。如果是,我们使用查询参数来初始化表单对象的一个字段。

实例说明

我们使用get_form_kwargs()方法来传递初始化参数,比如实现一个上传文件的表单:

from django.views.generic import FormView
from django.core.files.storage import FileSystemStorage
from django.conf import settings
from django import forms

class FileUploadForm(forms.Form):
    file = forms.FileField()

class FileUploadView(FormView):
    template_name = 'file_upload.html'
    form_class = FileUploadForm
    success_url = '/uploads/'

    def form_valid(self, form):
        fs = FileSystemStorage()
        fs.save(form.cleaned_data['file'].name, form.cleaned_data['file'])
        return super().form_valid(form)

在上面的代码中,我们创建了一个简单的表单类FileUploadForm和一个上传文件的视图FileUploadView。当用户提交表单时,我们在form_valid方法中保存用户上传的文件。

为了让上传文件更加方便,我们可以添加表单类中的初始化参数upload_dir,使上传文件的路径可以灵活设置:

class FileUploadForm(forms.Form):
    file = forms.FileField()

    def __init__(self, *args, **kwargs):
        upload_dir = kwargs.pop('upload_dir', None)
        super().__init__(*args, **kwargs)
        if upload_dir:
            self.fields['file'].widget.attrs.update({'accept': '.txt'})
            self.upload_dir = upload_dir

    def clean_file(self):
        data = self.cleaned_data['file']
        if data:
            ext = str(data).split('.')[-1]
            if ext != 'txt':
                raise forms.ValidationError("File type is not supported.")
        return data

    def save(self, commit=True):
        fs = FileSystemStorage(location=self.upload_dir)  
        filename = fs.save(self.cleaned_data['file'].name, self.cleaned_data['file'])
        return filename

class FileUploadView(FormView):
    template_name = 'file_upload.html'
    form_class = FileUploadForm
    success_url = '/uploads/'

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['upload_dir'] = settings.FILE_UPLOAD_DIR
        return kwargs

    def form_valid(self, form):
        filename = form.save()
        return super().form_valid(form)

在上面的代码中,我们对表单类FileUploadForm进行了修改。我们向__init__()方法添加了一个新的初始化参数upload_dir。如果我们提供了这个参数,我们将使用它来设置文件上传路径。我们还对表单进行了修改,使其只允许上传*.txt文件。代码中的clean_file方法用于验证文件类型。

在视图类FileUploadView中,我们重载了get_form_kwargs方法从而传递一个新参数upload_dir到表单类中。此外,我们还添加了一个与表单类中的save方法相对应的form_valid方法。在使用上传文件的时候我们只需要指定文件存放的位置即可。

所以我们发现,get_form_kwargs()可以灵活地传递初始化参数。在上面的例子中,我们使用这个方法向表单类中传递了上传文件目录的参数,从而使得用户可以选择文件上传的目录。