Cohen
Cohen

Reputation: 984

Django Admin Filter List Filter based on User Name for non-admins

I am using the django admin side and i want to filter the list filter items with the info that is available only for the non admin user. He is not allowed to even see the rest of the users in the filter side.

Can someone please help me to do this?

I have tried in models and admin:

def get_queryset(self, request):
        if not self.request.user.is_authenticated() or not self.request.user.is_superuser:
            user = request.user
            qs = super(ParkingModelAdmin, self).get_queryset(request)
            return qs.filter(user=request.user)

enter image description here

In this situation the loged user was elise.cohen so she should see only her details out there. Thank you!

 list_filter = ["parking_on", "user"]

My admin:

class ParkingModelAdmin(admin.ModelAdmin):
    list_display = ["user", "location","parking_on"]
    list_display_links = [ "location"]
    list_editable = [ "parking_on"]
    list_filter = ["parking_on", "user"]
    search_fields = ["location", "parking_on"]
    date_hierarchy = 'parking_on'

    class Meta:
        model = Parking

    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        if not obj:
            user = request.user
            form.base_fields['user'].initial = user
            form.base_fields['email'].initial = user.email
        return form

    def get_queryset(self, request):
        if not request.user.is_authenticated() or not request.user.is_superuser:
            user = request.user
            qs = super(ParkingModelAdmin, self).get_queryset(request)
            return qs.filter(user=user)

    def save_model(self, request, obj, form, change):  # add an additional message
        user = request.user
        messages.info(request, "Dear " + str(user)+ " "+ " please note that your parking plot has been reserved")
        super(ParkingModelAdmin, self).save_model(request, obj, form, change)

admin.site.register(Parking, ParkingModelAdmin)

MyModels:

class ParkingManager(models.Manager):
    def active(self, *args, **kwargs):
        return super(ParkingManager, self).filter(draft=False).filter(parking_on__lte=datetime.now())

class Parking(models.Model):
    PARKING_PLOT = (
        ('P1', 'Parking #1'),('P2', 'Parking #2'), ('P3', 'Parking #3'),
        ('P4', 'Parking #4'),('P5', 'Parking #5'), ('P6', 'Parking #6'),
        ('P7', 'Parking #7'),('P8', 'Parking #8'), ('P9', 'Parking #9'),
        ('P10', 'Parking #10'),('P11', 'Parking #11'), ('P12', 'Parking #12'),
        ('P13', 'Parking #13'),('P14', 'Parking #14'), ('P15', 'Parking #15')

    )
    user = models.ForeignKey(settings.AUTH_USER_MODEL,blank=True, null=True, default=1, on_delete=True)
    email = models.EmailField(blank=True, null=True)
    parking_on = models.DateField(auto_now=False, auto_now_add=False, blank=True, null=True,help_text='Please select the date you want to come in the office.',)
    parking_off = models.DateField(auto_now=False, auto_now_add=False, blank=True, null=True,help_text='Please select the date when you leave')
    numar_masina = models.CharField(max_length=8, default="IF77WXV", blank=True, null=True,help_text='Please insert your license plate number')
    location = models.CharField(max_length=3, blank=True, default="P1", null=True, choices=PARKING_PLOT,help_text='Please select the desired parking plot.')
    updated = models.DateTimeField(auto_now=True, auto_now_add=False, blank=True, null=True)
    timestamp = models.DateTimeField(auto_now=False, auto_now_add=True, blank=True, null=True)

    objects = ParkingManager()

    def __str__(self):
        return self.location + " | " + str(self.parking_on) + " | " + str(self.parking_off)

Upvotes: 1

Views: 2497

Answers (1)

not2acoder
not2acoder

Reputation: 1152

So If you want to limit the options in the user filter based on the logged in user, you may try using a custom filter as :

class UserFilter(admin.SimpleListFilter):
    title = 'User'
    parameter_name = 'user'

    def lookups(self, request, model_admin):
        user = request.user
        qs = YourUserModel.objects.filter(id=request.user.id)
        return ((obj.id, obj.username) for obj in qs)

    def queryset(self, request, queryset):
        if self.value():
            queryset = queryset.filter(user_id=self.value())
        return queryset

Now in the lookups method, depending on your user model you can limit the choices to display based on logged in user.

Upvotes: 1

Related Questions