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

发布于 2024-10-19 06:30:59 字数 911 浏览 0 评论 0原文

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

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

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

  3. 主题-- {标题、单位(外键)}

注意:(上面粗体字是模型名称,大括号中的值是每个模型的字段)

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

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

因此,我再次使用相同的 def queryset(self, request): 来过滤单元和主题,以仅显示分配给他/她的课程中的单元和主题。到目前为止,一切都很顺利,就像用户只能看到与他/她的课程相关的单元主题。但是,当用户尝试编辑单元时,会出现一个包含两个字段的表单:

  1. 标题(他可以重命名的单元的标题)
  2. 课程(所有课程的下拉列表)他可以选择任何人/外键)

在第二个字段“课程”下拉列表中,我只希望用户能够仅看到分配给他/她的那些课程。这样他/她就会无法使用未分配给他/她的任何其他课程来更新该单元。

与编辑主题时的情况相同,用户可以在下拉字段中看到所有单元,并可以为主题选择任何单元。

我想我需要覆盖一些视图或做一些魔法,但找不到。

I have implemented row level permission in my django admin application.I have my three models which are:

  1. Course-- {Title, code}

  2. Unit -- {Title, Course(foreign key)}

  3. Topic-- {Title, Unit(foreign key)}

Note: (Words above in bold are model names and values in curly braces are field for each model)

Every user has permission to add/edit/delete particular courses that are assigned to him/her. I am using def queryset(self, request): method to check which user has permission for which courses and then return a queryset with those courses. By that way I m able to display user particular courses assigned to him/her.

A course can have many Units and further a Unit can have many Topics.Its a hierarchy.

So I am using again same def queryset(self, request): for filtering Units and Topics to show only that Units and Topic that comes under course assigned to him/her. Till now everything goes well like user is able to see only those Units and topics which are related to his/her course. But when user tries to edit a unit a form appears with two fields:

  1. Title (title of unit that he can rename)
  2. course (Drop-down list of all courses from which he can choose anyone /foreign key)

In second field "course" drop-down I just want user to be able to see only those courses that are assigned to him/her.so that he/she would not be able to update the Unit with any other course that is not assigned to him/her.

Same case is with while editing Topics, a user can see all the Units in drop-down field and can select any unit for the topic.

I think I need to override some view or do some magic, but can't find out.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风筝有风,海豚有海 2024-10-26 06:30:59

您可能应该重写 ModelAdminUnitformfield_for_foreignkey 方法,以根据请求更改查询集。像(未经测试)的东西:

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)

You should probably override the formfield_for_foreignkey method in your ModelAdmin for Unit to alter the queryset based on the request. Something like (untested):

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)
独﹏钓一江月 2024-10-26 06:30:59

您可以使用 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()])

You can use django-smart-select

from smart_selects.db_fields import ChainedForeignKey

example code

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()])
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文