YusufD
YusufD

Reputation: 81

Django admin - property options based on a related parent model

I have a parent and a child class. The relation between them is many-to-one like this:

class Parent(AccessmanagerMixin, models.Model):
    name = models.CharField(max_length=150)
    def __str__(self) -> str:
        return self.name

class Child(AccessmanagerMixin, models.Model):
    name = models.CharField(max_length=150)
    parent_group = models.ForeignKey(Parent, on_delete=models.CASCADE,  null=True )
    def __str__(self) -> str:
        return self.name

they both have a many-to-many relation with the User class, named read_users (its a custom security on object level).

class AccessmanagerMixin(models.Model):
    read_users = models.ManyToManyField(User, related_name='read_users')
    class Meta:
        abstract = True

For example in the admin I would like to use the users from Parent read_users as an option for selecting the read_users for the Child entity? How can I do this in a best way? Can I override the read_users property in the Child admin.ModelAdmin.

Upvotes: 1

Views: 634

Answers (1)

Erik Kalkoken
Erik Kalkoken

Reputation: 32854

You can define which values are shown for a many-to-many field on the admin site with the formfield_for_manytomany() method.

Example for showing a union of the Parent's read_users for Child objects:

class ChildAdmin(admin.ModelAdmin):
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == "read_users":
            kwargs["queryset"] = User.objects.filter(pk__in=(list(Parent.objects.values_list("read_users__pk", flat=True))))
        return super().formfield_for_manytomany(db_field, request, **kwargs)

See official Django documentation for more details. 

Upvotes: 1

Related Questions