I have two models Restaurant and Details. The superuser assigns each restaurant a user.When that user logs into admin i want only those Details associated with that user's Restaurant to be shown,and he should be able to edit them as well.
I tried to override admin's queryset function but to no success.Any help would be appreciated. This is what i did so far
I am just a beginner in Django.
class RestaurantAdmin(admin.ModelAdmin):
model = Details
def save_model(self, request, obj, form, change):
obj.user = request.user
super(RestaurantAdmin, self).save_model(request, obj, form, change)
def queryset(self, request):
print(request.user)
qs = super(ResaturantAdmin, self).queryset(request)
# If super-user, show all comments
if request.user.is_superuser:
return qs
return qs.filter(owner=request.user)
admin.site.register(Restaurant)
admin.site.register(Details,RestaurantAdmin)
The method you need to override is called get_queryset, not queryset.
Related
I currently have a model that looks like this
class Sector():
featured_companies = models.ManyToManyField('Company', related_name='sectors')
def save(self, **kwargs):
super(Sector, self).save(**kwargs)
for company in self.featured_companies.all():
company.is_active = True
company.save()
I know that this doesn't work because of the way Django works on save. I read in another post that adding something like this to the admin should work:
def save_model(self, request, obj, form, change):
if obj.featured_companies:
form.cleaned_data['featured_companies'] = obj.featured_companies.all()
super(SectorAdmin, self).save_model(request, obj, form, change)
However, it is still not working. How would I accomplish editing the many to many field during the save process?
You can override the save_related(…) method [Django-doc] of your ModelAdmin and set the is_active field to True with a single query:
class SectorAdmin(ModelAdmin):
# …
def save_related(self, request, form, formsets, change):
super().save_related(request, form, formsets, change)
form.instance.featured_companies.all().update(
is_active=True
)
I want the admin users to see only the model instances they created. I followed these instructions Filter django admin by logged in user
class FilterUserAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
if getattr(obj, 'user', None) is None: #Assign user only the first time, superusers can edit without changing user
obj.user = request.user
obj.save()
def queryset(self, request):
qs = super(FilterUserAdmin, self).queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(user=request.user)
def has_change_permission(self, request, obj=None):
if not obj:
# the changelist itself
print('query change')
return True # So they can see the change list page
return obj.user == request.user or request.user.is_superuser
class CampaignAdmin(FilterUserAdmin):
...
This is how my code looks like. Everything works fine. I need one more model with campaign as foreign key.
class ScreenAdmin(FilterUserAdmin):
...
admin.site.register(Campaign,CampaignAdmin)
admin.site.register(Screen,ScreenAdmin)
now when I go to screens, and I see campaigns created by other users to select from
I don't want campaigns from other users to be able to be selected
Update: This is my current get_form
class ScreenAdmin(FilterUserAdmin):
list_display = ('screen_name', 'id','screen_URL')
def get_form(self, request, obj=None, **kwargs):
self.exclude = ["beacon"]
if not request.user.is_superuser:
self.exclude.append('user') #here!
form = super(ScreenAdmin, self).get_form(request, obj, **kwargs)
#print(vars(form))
form.base_fields['campaign'].queryset = Campaign.objects.filter(user=request.user)
return form
def changelist_view(self, request, extra_context=None):
if request.user.is_superuser:
self.list_display = ('screen_name','user', 'id','screen_URL')
#print('Change List######')
return super(ScreenAdmin, self).changelist_view(request, extra_context)
this solution is perfectly sane and working
def queryset(self, request):
qs = super(FilterUserAdmin, self).queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(user=request.user)
unless you are marked as superuser, an this is probably what you do.
to have access to the admin interface, you must check user as "staff" (is_staff)
if you check "superuser" you will see all of the data, so create other user (for the tests) add him proper rights, but do not mark mim as superuser, only is_staff and test it.
I want the admin users to see only the model instances they created. I followed these instructions Filter django admin by logged in user
class FilterUserAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
if getattr(obj, 'user', None) is None: #Assign user only the first time, superusers can edit without changing user
obj.user = request.user
obj.save()
def queryset(self, request):
qs = super(FilterUserAdmin, self).queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(user=request.user)
def has_change_permission(self, request, obj=None):
if not obj:
# the changelist itself
print('query change')
return True # So they can see the change list page
return obj.user == request.user or request.user.is_superuser
class CampaignAdmin(FilterUserAdmin):
...
This is how my code looks like.
Saving is fine.
However, other users are seeing the model campaign in their campaign list,
though they were not able to edit it. When a user, who is not the owner clicks the campaign to edit, 403 Forbidden page is seen.
I don't want the model instance to be shown in the other users' campaign list.
You should override get_queryset, not queryset. The method was renamed from queryset to get_queryset in Django 1.6.
def get_queryset(self, request):
qs = super(FilterUserAdmin, self).get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(user=request.user)
Note that you do not need to use getattr when checking if getattr(obj, 'user', None) is None:, you can simplify it to if obj.user is None.
I have a django model like this:
class Tour(models.Model):
Name=models.CharField(max_length=100)
Count=models.SmallIntegerField()
PriceUnitCode=models.ForeignKey(PriceUnit)
Price=models.CharField(max_length=12)
Description=models.TextField()
ActionDate=models.CharField(max_length=16)
ActionUser=models.ForeignKey(User)
When a user logs in the admin site, I would want the user to see only the Tour instances he has created (Tour instances for which the ActionUser is equal to the ID of logged-in user).
How can I filter the changelist based on logged-in users?
Thanks buddy
I tryed your code but it had error!!so I changed it and now it work well:
class TourAdmin(admin.ModelAdmin):
def queryset(self, request):
qs = super(TourAdmin, self).queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(ActionUserCode=request.user)
admin.site.register(Tour,TourAdmin)
I put code for others who may have such problem
in admins.py
class MyRegisteredTourAdmin(admin.ModelAdmin):
def queryset(self, request):
qs = Tour.objects.filter(action_user=request.user)
return qs
admin.site.register(Tour,MyRegisteredTourAdmin)
I've tried numerous methods of finding the current user ID in django's administration. I've tried pulling the user ID via SessionKey and request.user (HTTPRequest) to no avail. My latest incarnation is:
def save(self, request, obj, form, change):
if getattr(obj, 'submitter', None) is None:
obj.submitter = request.user
obj.save()
super(AppAdmin, self).save()
in admin.py and
submitter = models.ForeignKey(User, null=True, blank=True, related_name="submitter")
in models.py. I found this elsewhere on stack overflow, but it doesn't seem to work. Any help is appreciated.
Thanks!
From the looks of your snippet, you are trying to save the currently logged in user to your model field in a ModelAdmin
It looks like you meant to override save_model
http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_model
class AppAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.submitter = request.user # no need to check for it.
obj.save()