How to customize the list_display option in django using queryset?
<p>I want to make a course guidance app for my college. Here is my model.py</p>

<pre><code>from django.db import models
from django.contrib.auth.models import User

# Create your models here.

class Instructor(models.Model):
    name = models.CharField(max_length=200)
    owner = models.ForeignKey(User)
    # other stuff here 
    def __str__(self):
        return self.name

class Course(models.Model):
    course_code = models.CharField(max_length=10, default='CS')
    instructor = models.ForeignKey(Instructor)
    course_name = models.CharField(max_length=200)
    # other stuff here 
    def __str__(self):
        return self.course_name

class CourseOutline(models.Model):
    course = models.OneToOneField(Course)
    objectives = models.TextField(blank=True)
    # other stuff
</code></pre>

<p>And this this my admin.py</p>

<pre><code>from django.contrib import admin
from models import Course, CourseOutline, Instructor

# Register your models here.
admin.site.register(Instructor)
class CourseAdmin(admin.ModelAdmin):

    # some other stuff 
    def queryset(self, request):
        qs = super(CourseAdmin, self).queryset(request)
        if request.user.is_superuser:
            return qs


        # get instructor's "owner" 
        return qs.filter(instructor__owner=request.user)

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "instructor" and not request.user.is_superuser:
            kwargs["queryset"] = Instructor.objects.filter(owner=request.user)
            return db_field.formfield(**kwargs)
        return super(CourseAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

    list_display = ('course_name', 'instructor')
    list_filter = ('queryset',)

admin.site.register(Course, CourseAdmin)

class CourseOutlineAdmin(admin.ModelAdmin):
    # nothing here of importance

    # whatever was here

    def queryset(self, request):
        qs = super(CourseOutlineAdmin, self).queryset(request)
        if request.user.is_superuser:
            return qs
        # get instructor's "owner"
        return qs.filter(course__instructor__owner=request.user)

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "course" and not request.user.is_superuser:
            kwargs["queryset"] = Course.objects.filter(instructor__owner=request.user)
            return db_field.formfield(**kwargs)
        return super(CourseAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

admin.site.register(CourseOutline, CourseOutlineAdmin)
</code></pre>

<p>Here i'm using row level permission for instructors so that they can only add courses related to them and add course outline to those courses only to which they are related. That's why i used instructor as foreign key for courses and wrote a function to manipulate the foreign key drop-down menu so that only their name will come in the drop-down menu. But when they are seeing the courses they can watch other instructor's courses and if they have privileges to delete courses then they can delete courses of other instructor's also. So i want that they can see only those courses in the list which they own only. In one post i have seen the queryset function and tried to implement it but it doesn't solved my problem.</p>

<p>Your code is mostly right but the method is actually <code>get_queryset</code> rather than <code>queryset</code> you've probably mixed it up with the queryset property</p>

<pre><code>def get_queryset(self, request):
    qs = super(CourseAdmin, self).get_queryset(request)
    if request.user.is_superuser:
        return qs


    # get instructor's "owner" 
    return qs.filter(instructor__owner=request.user)
</code></pre>

<p>Note that if you are super user you will still be able to see everyone else's courses, so make sure that you login as a less privileged user. You will need to change the method name in the other class too.</p>

python django django-admin django-authentication