Reputation: 705
I want to restrict which rows appear in the Django admin console based on the user that is logged in. Using the AuthUser model, I have created the following Account model which links Django user accounts to specific businesses in my database:
class Account(models.Model):
id = models.AutoField(primary_key=True, editable=False)
username_id = models.ForeignKey('AuthUser', db_column='username_id')
business_id = models.ForeignKey('Business', db_column='business_id')
Here is my Business model:
class Business(models.Model):
id = models.AutoField(primary_key=True, editable=False)
name = models.CharField(max_length=45)
address = models.CharField(max_length=45)
When the user logs in, I want to restrict the user so they can only add/view/delete entries into/from my database (through the Django admin console) for their respective business. Here is my Entry model:
class Entry(models.Model):
id = models.AutoField(primary_key=True, editable=False)
business = models.ForeignKey('Business')
entry_text = models.CharField(max_length=300)
created = models.DateField(auto_now=True)
Is there an easy way to get this accomplished?
Upvotes: 1
Views: 883
Reputation: 4043
In your model admin, you could override the method get_queryset()
.
So you could do something like,
class EntryAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super(EntryAdmin, self).get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(business__in=request.user.account_set.all().values_list('business_id', flat=True))
The last line, qs.filter(business__in=request.user.account_set.all().values_list('business_id', flat=True))
, filters the initial queryset(which defaults to all entries).
request.user.account_set.all()
returns all the Account
objects associated with the user. Yes, the way you design your Account
model will allow multiple objects to be associated to a User. If you want to limit it to one, you should consider using OneToOneField
.
Appending .values_list('business_id', flat=True)
to the queryset is telling Django that you only want specific columns to be returned, in this case just the business_id
column. values_list
returns a list of tuples but if you only need one column from the queryset, you can pass the keyword argument flat=True
which will return a flat list.
Upvotes: 3