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:
Course-- {Title, code}
Unit -- {Title, Course(foreign key)}
- 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:
- Title (title of unit that he can rename)
- 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()])
精彩评论