Search code examples
djangodjango-modelsdjango-admin

Trying to filter "managers" field to only show managers in the currently logged in user's department


I have three models:

  • The base User model that Django provides
  • UserProfile, a model that has 2 fields:
    a foreignkey field with the user table
    a department field that's a choicefield with a dropdown, every user has 1 department
  • A Data model that contains a Manager field, a many-to-many with the user model

Models:

class Data(models.Model):
    """Model representing each event's data."""
    title = models.CharField(max_length=200)
    description = models.TextField(max_length = 2000)
    managers = models.ManyToManyField(User, related_name="event_co_manager_user", 
                                      blank=True)

class UserProfile(models.Model):
    """Model representing the user profile"""
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    DEPARTMENT_CHOICES = (
        (0, 'Dep1'),
        (1, 'Dep2'),
        (2, 'Dep3'),
    )

    department = models.PositiveSmallIntegerField(choices=DEPARTMENT_CHOICES, 
                                 null=True)

I am trying to filter the manager field on the backend to only show managers that share the same department, since we don't want people to be able to add other departments as managers in their events.

This is the function that I'm trying to overwrite in my admin.py (using Django 5.0):

def formfield_for_manytomany(self, db_field, request, **kwargs):
    if db_field.name == "managers":
        kwargs["queryset"] = Data.objects.filter(
            managers.userprofile.department == request.user.userprofile.department
        )

    return super().formfield_for_manytomany(db_field, request, **kwargs)

I keep getting errors about the managers field not having an attribute of userprofile.


Solution

  • When you want to construct a query that will span relationships, such as when you want to filter on a ForeignKey attribute, you need to use dunder instead of period to access those relationships.

    Replace:

    Data.objects.filter(managers.userprofile.department ==
    

    with:

    Data.objects.filter(managers__userprofile__department ==