最近在为部门做一个文档管理系统,基本架构是:django+nginx+uwsgi+mysql
遇到一个问题,文件上传的时候需要添加tag标签,我想要的结果是每个人有每个人自己自定义的标签,即每个人标签的queryset不同,怎么区别自定义的标签呢,很简单,给标签表加个user外键,我命名为owner
1.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.Form):
# 注意这里的init函数使用之后只是初始化tag域,并没有生成form项
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%',
}
),
)
# 这里才是真正生成form项的地方,所以GET的时候生成的form如下图
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 = "公开",
)
为什么用Tag.objects.none()
stackoverflow上国外友人有一句话:
See my updated answer. ModelChoiceField
requires
a queryset. You can use the empty queryset, since you set the real queryset in the __init__
method.
--------------------------------------------------------------------------------附图--
2.views.py
def UploadView(request):
activeUpload = "active"
# 如果是get,初始化一下,并把user传给form的init函数用来过滤自定义的tag
if request.method == 'GET':
form = FileForm(
user=request.user,
initial = {
'public': '1',
'deleted': '0',
},
)
return render_to_response('app_filemanager/upload.html', context_instance=RequestContext(request,locals()))
# 如果是post,虽然不需要过滤tag了,但是因为form的init函数需要user,所以这里也把request.user当一个变量传过去
else:
form = FileForm(request.user, request.POST, request.FILES)
if form.is_valid():
f = File.allFiles.create(
file = request.FILES['file'],
public = form.cleaned_data['public'],
project = form.cleaned_data['project'],
uploader = User.objects.get(username = request.user.username),
deleted = form.cleaned_data['deleted'],
desc = form.cleaned_data['desc'],
upload_date = datetime.datetime.now(),
change_date = datetime.datetime.now(),
tag = form.cleaned_data['tag'],
)
group = form.cleaned_data['group']
for g in group:
f.group.add(g)
f.save()
return render_to_response('app_filemanager/success.html', context_instance=RequestContext(request,locals()))
else:
return render_to_response('app_filemanager/upload.html', context_instance=RequestContext(request,locals()))