首页 > 代码库 > django:通用视图-UpdateView更新有参数的form类

django:通用视图-UpdateView更新有参数的form类

这个提示放在开始:要想使用通用视图更新form,那么这个form的类型必须是ModelForm,

即:

class FileForm(forms.ModelForm):
    ....

不要问我为什么知道的

------------------------------------------------------------------------------------------------------

首先:urls.py

#coding=utf-8
from django.conf.urls import patterns,url
from app_filemanager import views


urlpatterns=patterns('',
    ...
    url(r'^(?P<pk>\d+)/update/$', views.FileUpdateView.as_view(), name='update'),
    # 通用视图传值统一使用pk作为变量名,而这个pk往往都是model自己生成的那个编号,所以后面正则匹配用d+
)

然后:forms.py

#coding=utf8
from django import forms
from .models import File, Project, Tag
from django.contrib.auth.models import User, Group

class FileForm(forms.ModelForm):

    def __init__(self, user, *args, **kwargs):
        super(FileForm, self).__init__(*args, **kwargs)
        self.fields['tag'] = forms.ModelChoiceField(
            queryset = Tag.objects.filter(owner=user),
            required = True,
            label = "分类",
            help_text = "不能为空,个人文档分类使用",
            error_messages = {'required': "以下是必填项"},
            empty_label = "请至少选择一个",
            widget = forms.Select(
                attrs = {
                    'class': 'form-control',
                    'style': 'width:100%',
                }
            ),
        )
    project = forms.ModelChoiceField(
        queryset = Project.publicProjects.order_by('-add_date'),
        required = False,
        label = "所属项目",
        help_text = "可为空,为了防止混淆,一个文档只能属于一个项目",
        error_messages = {'required': "以下是必填项"},
        widget = forms.Select(
            attrs = {
                'class': 'form-control',
                'style': 'width:100%',
            }
        ),
    )
    tag = forms.ModelChoiceField(
        queryset = Tag.objects.none(),
    )

    group = forms.ModelMultipleChoiceField(
        queryset = Group.objects.order_by('-id'),
        required = True,
        label = "哪些组可见",
        help_text = "可以多选",
        error_messages = {'required': "以下至少选择一个"},
        widget = forms.SelectMultiple(
            attrs = {
                'class': 'form-control',
                'style': 'width:100%'
            }
        ),
    )

    desc = forms.CharField(
        required = False,
        label = "描述",
        widget = forms.Textarea(
            attrs = {
                'placeholder': u'可以通过描述查找文档',
                'rows': 2,
                'style': 'width:100%',
                'class': 'form-control',
            }
        ),
    )

    file = forms.FileField(
        required = True,
        label = "文档",
        help_text = "大小限制为1G",
        error_messages = {'required': "请选择一个文件"},
    )


    deleted = forms.BooleanField(
        required = False,
        label = "选中则标记为删除",
        help_text = "默认公开,个人文件不会被项目归类",
        widget = forms.HiddenInput(
            attrs = {
                'style': 'width:100%',
                'class': 'form-control',
            }
        ),
    )

    public = forms.BooleanField(
        required = False,
        label = "公开",
        #help_text = "选中为公开,个人文件不会被项目归类",
    )
    class Meta:
        model = File
        fields = ('project', 'tag', 'group', 'desc', 'file', 'public')

关于form类里的init方法,你可以参考我的上篇,这里

上篇博文是如何将request.user传到form里面,这里讲一下如何在update通用视图传user

再然后:views.py

class FileUpdateView(UpdateView):
    model = File
    template_name_suffix = '_update_form'
    success_url = '/file/'
    permission_required = 'app_filemanager.can_change_file'
    permission_fail_message = ('You don\'t have permission to change employee info.')
    form_class = FileForm
    def get_form_kwargs(self):
        kwargs = super(FileUpdateView, self).get_form_kwargs()
        kwargs.update({
            'user':self.request.user
        })
        return kwargs

最后:file_update_form.html

{% extends "base.html" %}
{% block content_middle %}
<form action="" method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" class="btn btn-default" value=http://www.mamicode.com/"Update" />>

附上效果图:

技术分享

就是这么简单,所以说django的form类如果会用并且灵活应用的话是很省事的,有问题留言

django:通用视图-UpdateView更新有参数的form类