I have a model for Orders in an application for a web store with an automatically increasing primary key and a foreign key for myself, since orders can be divided into several orders, but communication with the original order must be supported.
class Order(models.Model): ordernumber = models.AutoField(primary_key=True) parent_order = models.ForeignKey('self', null=True, blank=True, related_name='child_orders')
I registered the OrderAdmin class for the admin site. For a detailed view, I have included parent_order in the fieldsets attribute. Of course, by default, all orders are listed on this list, but this is not the desired behavior. Instead, for orders that do not have a parent order (i.e., were not separated from another order, parent_order is NULL / None), no orders should be displayed. For orders that have been split, this should only display one parent order.
A fairly new ModelAdmin method, formfield_for_foreignkey, is formfield_for_foreignkey , which seems ideal for this, since the request can be filtered out in it. Imagine that we are looking at the detailed view of order No. 11234, which was divided into order # 11208. The code below
def formfield_for_foreignkey(self, db_field, request, **kwargs): if db_field.name == 'parent_order':
The commented line works when launched in the Python shell, returning a single-item selection request containing the order # 11208 for # 11234 and all other orders that can be divided into it.
Of course, we cannot hard code the order number. We need a link to the ordernumber field of the ordernumber instance whose detailed page we are looking at. Like this:
kwargs["queryset"] = Order.objects.filter(child_orders__ordernumber__exact=?????)
I did not find a replacement job with reference to the "current" instance of the order, and I dug quite deeply. self inside formfield_for_foreignkey refers to an instance of ModelAdmin, and although it has a model attribute, it is not an instance of the order model (this is a ModelBase reference; self.model () returns an instance, but its serial number is None).
One solution might be to pull the order number from request.path (/ admin / orders / order / 11234 /), but it is really ugly. I am very sorry that there is a better way.