So in one app i have four models. From first to last they are name 'brand', 'mark', 'type', 'engine'.
Mark has a foreign key to brand, type has a foreign key to mark, and engine has one to type.
In the admin interface when I add a mark I get a dropdown list to choose from all the Brands. When I add a type, I get a dropdown list to choose from all the Marks.
What I want: when I am adding a Type, I want to also be able to choose the Brand from a dropdown list, and that choice, to filter the next dropdown from Marks.
from django.contrib import admin from .models import a_brand, b_mark, c_type, d_engine from .forms import TypeModelAdminForm
these are my models
from django.db import models
class a_brand(models.Model):
brand_name = models.CharField(max_length=250, unique=True)
brand_logo = models.ImageField(
upload_to='C:/Users/Robert/Desktop/carsbook/static/catalog/brandslogos'
)
class Meta:
ordering = ['brand_name']
def __str__(self):
return self.brand_name
class b_mark(models.Model):
mark_brand = models.ForeignKey(a_brand, on_delete=models.CASCADE)
mark_name = models.CharField(max_length=250)
mark_image = models.ImageField(
upload_to='C:/Users/Robert/Desktop/carsbook/static/catalog/marksimages',
default='C:/Users/Robert/Desktop/carsbook/static/default/default.jpg'
)
class Meta:
unique_together = ("mark_brand", "mark_name")
ordering = ['mark_brand', 'mark_name']
def __str__(self):
return self.mark_name
class c_type(models.Model):
type_mark = models.ForeignKey(b_mark, on_delete=models.CASCADE)
type_name = models.CharField(max_length=250)
type_image = models.ImageField(
upload_to='C:/Users/Robert/Desktop/carsbook/static/catalog/typesimages',
default='C:/Users/Robert/Desktop/carsbook/static/default/default.jpg'
)
class Meta:
unique_together = ("type_mark", "type_name")
ordering = ['type_mark', 'type_name']
def __str__(self):
return self.type_name
class d_engine(models.Model):
engine_type = models.ForeignKey(c_type, on_delete=models.CASCADE)
engine_name = models.CharField(max_length=250)
class Meta:
unique_together = ("engine_type", "engine_name")
ordering = ['engine_type', 'engine_name']
def __str__(self):
return self.engine_name
this is what I have in my admin.py
from django.contrib import admin
from .models import a_brand, b_mark, c_type, d_engine
from .forms import TypeModelAdminForm
class b_markModelAdmin(admin.ModelAdmin):
list_display = ["brand", "__str__"]
search_fields = ["mark_brand__brand_name", "mark_name"]
list_display_links = ["__str__"]
class Meta:
model = b_mark
def brand(self, instance):
return instance.mark_brand
class c_typeModelAdmin(admin.ModelAdmin):
form = TypeModelAdminForm
list_display = ["brand", "type_mark", "__str__"]
search_fields = ["type_name", "type_mark__mark_name", "type_mark__mark_brand__brand_name"]
list_display_links = ["__str__"]
class Meta:
model = c_type
def brand(self, instance):
return instance.type_mark.mark_brand
def mark(self, instance):
return instance.type_mark
class d_engineModelAdmin(admin.ModelAdmin):
list_display = ["brand", "mark", "type", "__str__"]
search_fields = [
"engine_name",
"engine_type__type_name",
"engine_type__type_mark__mark_name",
"engine_type__type_mark__mark_brand__brand_name"
]
list_display_links = ["__str__"]
class Meta:
model = d_engine
def brand(self, instance):
return instance.engine_type.type_mark.mark_brand
def mark(self, instance):
return instance.engine_type.type_mark
def type(self, instance):
return instance.engine_type
admin.site.register(a_brand)
admin.site.register(b_mark, b_markModelAdmin)
admin.site.register(c_type, c_typeModelAdmin)
admin.site.register(d_engine, d_engineModelAdmin)
When I am in my admin site, and am adding an c_type or d_engine model, to be able not only to choose the foreign key of the "upper" model, but instead filter them based on brand, then mark, then engine.
So for example, when I am adding en d_engine, I have to choose a foreignkey from all the types, from all the marks, from all the brands. Instead I want to first somehow choose the brand first, the chosen brand to filter, the next drowdown list of marks, then the selected mark, to filter the types, and only then I chose the c_type.
It is kind of confusing to explain.