寻求有关群组和权限的帮助

时间:2015-06-17 06:31:07

标签: django django-forms django-permissions

我目前正在开发一个允许用户上传文档的项目。文档有三种不同的类型,每个用户都有权创建/更改/删除一个或多个这些类型。这是我的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)

这可能不是解决问题的最有效方法。

1 个答案:

答案 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)