我目前正在开发一个允许用户上传文档的项目。文档有三种不同的类型,每个用户都有权创建/更改/删除一个或多个这些类型。这是我的django型号:
class Well(models.Model):
name = models.CharField("well_name",max_length=20)
location = models.CharField("well_location",max_length=20)
def __str__(self):
return self.name
class Document(models.Model):
DOC_TYPE = (
('gto','Geo Technical Order'),
('ewr','End Well Report'),
('qpr','Quarterly Progress Report'),
)
class Meta:
permissions = (("add_gto","Can upload GTO"),("add_ewr","Can upload EWR"),("add_qpr","Can upload QPR"),)
docfile = models.FileField("file")
title = models.CharField("doc_title",max_length=50)
pub_date = models.DateTimeField("pub_date",auto_now_add=True)
remark = models.TextField(max_length=200,blank=True)
publisher = models.ForeignKey(User,null=True)
doc_type = models.CharField("doc_type",choices=DOC_TYPE,max_length=3)
well = models.ForeignKey(Well)
这是我的forms.py:
class DocumentForm(ModelForm):
class Meta:
model = Document
fields = ['docfile','title','remark','doc_type','well']
exclude = ('publisher',)
def __init__(self,publisher,*args,**kwargs):
super(DocumentForm,self).__init__(*args,**kwargs)
#self.user = publisher
#upermission = Permission.objects.filter(user=publisher)
upermission = publisher.get_all_permissions()
u = publisher.user_permissions.all()
#self.fields['doc_type'].choices = [(k,v) for k,v in Document.DOC_TYPE.iteritems() if k in upermission]
#self.fields['doc_type'].choices = [v for v in Document.DOC_TYPE.itervalues() if k in upermission]
#self.fields['doc_type'] = forms.ModelChoiceField(queryset = Document.objects.filter(publisher= publisher))
self.fields['doc_type'] = forms.ModelChoiceField(queryset = u)
编辑:使用来自forms.py和清晰语言的更多代码更新了问题。
我已通过管理界面向用户授予“可以上传GTO”的权限。 现在生成表单,但下拉列表显示以下格式的选项: appname | modelname |权限即。 welldocs | document |可以上传GTO,当我提交表单时,我收到此错误:选择一个有效的选项。这个选择不是可用的选择之一。
我希望下拉列表显示与DOC_TYPE对应的值。在这种情况下,它应该是'地理技术订单'。
编辑2:在尝试代号而不是code_name之后,它仍然显示语法错误。但是,我设法通过这样的方式来解决问题:
u = publisher.user_permissions.all()
elist = []
etup = tuple(elist)
if not u:
self.fields['doc_type'] = forms.ChoiceField(choices = etup)
else:
codename_list = []
name_list = []
for p in u:
p.codename = p.codename.replace("add_", "")
p.name = p.name.replace("Can upload ", "")
codename_list.append(p.codename)
name_list.append(p.name)
tup = tuple(zip(codename_list,name_list))
self.fields['doc_type'] = forms.ChoiceField(choices = tup)
现在下拉字段显示GTO而不是Geo Technical Order,但表单提交正常并且文档上传。但是如果你包含除三个自定义权限之外的权限,这将失败,因为下拉列表会显示appname | modelname |权限,我会得到错误:选择一个有效的选择。这个选择不是可用的选择之一。 有没有办法解决这个问题,以便您只能包含分配的自定义权限而不是所有权限?
EDIT3:通过这样做解决了上述问题:
for p in u:
codename = p.codename.replace("add_", "")
p.name = p.name.replace("Can upload ", "")
if('GTO' in p.name or 'EWR' in p.name or 'QPR' in p.name):
codename_list.append(p.codename)
name_list.append(p.name)
tup = tuple(zip(codename_list,name_list))
self.fields['doc_type'] = forms.ChoiceField(choices = tup)
这可能不是解决问题的最有效方法。
答案 0 :(得分:0)
第一步,模型中的一个小变化
class Document(models.Model):
GTO = 'gto'
EWR = 'ewr'
QPR = 'qpr'
DOC_TYPE = {
GTO: 'Geo Technical Order',
EWR: 'End Well Report',
QPR: 'Quarterly Progress Report',}
docfile = models.FileField("file")
title = models.CharField("doc_title", max_length=50)
pub_date = models.DateTimeField("pub_date", auto_now_add=True)
remark = models.TextField(max_length=200, blank=True)
publisher = models.ForeignKey(User)
doc_type = models.CharField("doc_type", choices=DOC_TYPE.items(), max_length=3)
well = models.ForeignKey(Well)
让我们创建一个ModelForm
class DocumentForm(forms.ModelForm):
class Meta:
model = Document
fields = ['doc_type', 'title', 'remark', 'docfile']
def __init__(self, well, publisher, *args, **kwargs):
super(DocumentForm, self).__init__(*args, **kwargs)
self.well = well
self.publisher = publisher
permissions = user.get_all_permissions()
# The linked answer in your comment replaced the field,
# I choose to overwrite the choices
self.fields['doc_type'].choices = [(k, v)
for k, v in Document.DOC_TYPE.iteritems()
if k in permissions ]
def save(self, commit=True):
doc = super(DocumentForm, self).save(commit=False)
doc.publisher = self.user
doc.well = self.well
doc.save()
return doc
您的解决方案(forms.ModelChoiceField(queryset = upermission)
)存在upermission是一个集合的问题,并且需要QuerySet。对于ChoiceField是预期的元组列表或元组。因此,您可以将其更改为:forms.ChoiceField(choices=[(v, v) for v in upermission])
==问题更新后编辑==
问题出在这一行:
self.fields['doc_type'] = forms.ModelChoiceField(queryset = u)
POST后问题是doc_type
是CharField,您选择的是Permission
个对象。这显然是冲突。将其更改为以下内容。
u = [(p.code_name.replace("add_", ""), p.name.replace("Can upload ", "")
for p in publisher.user_permissions.all().iterator()]
self.fields['doc_type'] = forms.ChoiceField(choices=u)