如何在django admin中自定义表单值以仅显示分配给他/她的那些值?

时间:2011-02-25 18:43:12

标签: django django-models django-admin django-forms

我已经在我的django管理应用程序中实现了行级权限。我有三个模型:

  1. 课程 - {标题,代码}

  2. 单位 - {标题,课程(外键)}

  3. 主题 - {标题,单位(外键)}
  4. 注意:(上面的粗体字是模型名称,花括号中的值是每个模型的字段)

    每位用户都有权添加/编辑/删除分配给他/她的特定课程。我使用def queryset(self, request):方法检查哪个用户有权使用哪些课程,然后返回带有这些课程的查询集。通过这种方式,我可以显示分配给他/她的用户特定课程。

    课程可以有多个单元,而且单元可以有多个主题。它是一个层次结构。

    所以我再次使用相同的def queryset(self, request):来过滤单位和主题,以仅显示分配给他/她的课程中的单元和主题。直到现在一切顺利,用户只能看到与他/她的课程相关的单元主题。但是,当用户尝试编辑单元时,表单会显示两个字段:

    1. 标题(他可以重命名的单位名称)
    2. 课程(所有课程的下拉列表,他可以从中选择任何人/外键)
    3. 在第二个字段“course”下拉列表中,我只希望用户只能看到分配给他/她的那些课程,因为他/她将无法更新该单位的任何其他课程未分配给他/她。

      同样的情况是,在编辑主题时,用户可以在下拉字段中查看所有单位,并可以选择该主题的任何单位。

      我认为我需要覆盖一些观点或做一些魔术,但无法找到。

2 个答案:

答案 0 :(得分:1)

您应该覆盖formfield_for_foreignkey ModelAdmin中的Unit方法,以便class UnitAdmin(admin.ModelAdmin): def formfield_for_foreignkey(self, db_field, request=None, **kwargs): if db_field.name == 'course': # filter queryset somehow based on request.user: kwargs['queryset'] = db_field.rel.to._default_manager.filter(...) return super( UnitAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) 根据请求更改查询集。像(未经测试)的东西:

{{1}}

答案 1 :(得分:1)

您可以使用django-smart-select

from smart_selects.db_fields import ChainedForeignKey

示例代码

from django.db import models
from smart_selects.db_fields import ChainedForeignKey

class Continent(models.Model):
    name = models.CharField(max_length=100)
    def __unicode__(self):
        return self.name

class Country(models.Model):
    name=models.CharField(max_length=100)
    continent=models.ForeignKey(Continent)
    def __unicode__(self):
        return self.name

class Area(models.Model):
    name=models.CharField(max_length=100)
    country=models.ForeignKey(Country)
    def __unicode__(self):
        return self.name

class Location(models.Model):
    continent = models.ForeignKey(Continent)
    country = ChainedForeignKey(
        Country, 
        chained_field="continent",
        chained_model_field="continent", 
        show_all=False, 
        auto_choose=True
    )
    area = ChainedForeignKey(Area, chained_field="country", chained_model_field="country")
    city = models.CharField(max_length=50)
    street = models.CharField(max_length=100)

    def get_products(self):
        return ','.join([p.name for p in self.area.all()])