Home > database >  How to see objects of manytomany field by related_name in admin page?
How to see objects of manytomany field by related_name in admin page?

Time:07-07

I have these two models:

class User(AbstractUser):
    is_teacher = models.BooleanField(default=False, null=False)
class Course(models.Model):
    teacher = models.ForeignKey(User, on_delete=models.CASCADE, related_name='teacher_courses')
    students = models.ManyToManyField(User, blank=True, related_name='student_courses')

Course model has a ManyToMany field and a ForeignKey to User model. In django's admin page, you are able to see a course's student/teacher. Is there a way to make it as you can have a list of a user's courses in admin page to see/add/remove courses for a user?

CodePudding user response:

You can define a callable on your ModelAdmin class and add it to list_display. To make the courses editable on an user's page use sub classes of InlineModelAdmin.

class TeacherCourseInlineAdmin(admin.TabularInline):
     model = Course
     fk_name = "teacher"
     

class StudentCourseInlineAdmin(admin.TabularInline):
     model = Course
     fk_name = "student"


class UserAdmin(admin.ModelAdmin):
    list_display = ("username", "teacher_courses")
    inlines = [TeacherCourseInlineAdmin, StudentCourseInlineAdmin]

     def get_queryset(self, *args, **kwargs):
         return super().get_queryset(*args, **kwargs).prefetch_related("teacher_courses")

     @admin.display(description='Courses')
     def teacher_courses(self, user):
         return [c.name for c in user.teacher_courses.all()] 

Note that it makes sense to override ModelAdmin.get_queryset() to add a call to prefetch_related() so that Django fetches all related courses in one extra query instead of performing one additional query for every user object.

  • Related