开发者

how do I customize the form values in django admin to show only those values that are assigned to him/her?

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 ha开发者_开发知识库ve 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.


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)


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()])
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜