Myzel394
Myzel394

Reputation: 1317

Django custom manager return everything when user is on admin page

I'm creating a Django app. It's an article app. I have a field named hidden and I want to return a queryset without articles when hidden is true and the user isn't in the admin panel.

Admin-page -> Show everything

Normal search -> Show only with hidden = False

My "Normal Search" is a custom search I made. I'm filtering results with django-filter and I want to automatically filter out hidden articles.

I'm creating this with a custom manager:

class ArticleManager(models.Manager):
    def get_queryset(self, request):
        if request.user.is_superuser:
            return super().get_queryset()
        return super().get_queryset().filter(hidden=False)

but I'm just getting this error:

TypeError: get_queryset() missing 1 required positional argument: 'request'

Upvotes: 0

Views: 445

Answers (2)

malberts
malberts

Reputation: 2536

Based on the updated question: You shouldn't redefine the model manager's get_queryset function signature to take a request parameter. Instead, you need to create a new manager function with a user parameter which will return only the items you want. You will then use that as the queryset to your filter.

For example:

class ArticleManager(models.Manager):
    def get_visible_items(self, user):
        if user.is_superuser:
            return super().get_queryset()
        return super().get_queryset().filter(hidden=False)

# In your view:
user = request.user
artice_filter = ArticleFilter(queryset=Article.objects.get_visible_items(user))

Upvotes: 1

Bernhard Vallant
Bernhard Vallant

Reputation: 50786

Usually no request instance would get passed to manager methods. But you can customize the queryset used inside an admin using its get_queryset() method:

class ArticleAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        qs = super().get_queryset(request)
        if request.user.is_superuser:
            return qs
        return qs.filter(hidden=False)

Note that this queryset will also get for editing instances, so you can really restrict which objects are accessible for certain users.

Upvotes: 1

Related Questions