G
G
Gadd2016-01-17 16:54:42
Django
Gadd, 2016-01-17 16:54:42

DjangoAdmin how to implement dependent select in list_filter?

Hello!
I'm training in Django 1.8. There is the following model in the address application:

class City(models.Model):
    name = models.CharField("город", unique=True, max_length=30)


class Street(models.Model):
    name = models.CharField("улица", max_length=50)
    city = models.ForeignKey(City, verbose_name="город")

In the admin panel I made filters by city and street:
class AddressAdmin(admin.ModelAdmin):
    list_filter = ['address__street__city__name', 'address__street__name']

How to make it so that when you select a city in the list of streets, only the streets of the selected city are displayed? The current version displays all cities and all streets in all cities.
I looked at the documentation, I did not find a built-in solution yet.
UPD:
Thanks for the advice, I did something like this:
class StreetListFilter(admin.SimpleListFilter):
    title = 'улицы'
    parameter_name = 'street'

    def lookups(self, request, model_admin):  # будем выводить улицы только выбранного города
        city_name = request.GET.get('address__street__city__name')
        streets_list = list()
        if city_name:
            streets = Street.objects.filter(city__name=city_name)  # получаем названия всех улиц города
            for i in streets:
                streets_list.append((i.get_name(), i.get_name()))
            return streets_list

    def queryset(self, request, queryset):
        if self.value():
            city_name = request.GET.get('address__street__city__name')
            city = City.objects.get(name=city_name)
            return queryset.filter(address__street=Street.objects.get(name=self.value(), city=city))


class AddressAdmin(admin.ModelAdmin):
    list_filter = ['address__street__city__name', StreetListFilter]

However, the question remains, how to remove the previously selected street from the GET parameters when choosing another city
UPD2:
To the last question, I decided this way: I
added a small construction to lookups:
def lookups(self, request, model_admin):  # будем выводить улицы только выбранного города
        city_name = request.GET.get('address__street__city__name')
        streets_list = list()
        if city_name != request.session.get('stored_city_name'):  # new ###########
            self.used_parameters[self.parameter_name] = None  ##### new ###########
            request.session['stored_city_name'] = city_name  ###### new ###########
        if city_name:
            streets = Street.objects.filter(city__name=city_name)  # получаем названия всех улиц города
            for i in streets:
                streets_list.append((i.get_name(), i.get_name()))
            return streets_list

How "dirty hack" is this and is it worth it?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
R
Rostislav Grigoriev, 2016-01-17
@Gadd

Have you looked at this in the documentation?
https://docs.djangoproject.com/en/1.8/ref/contrib/...
Inherit from SimpleListFilter and in the necessary methods make your selection depending on what is passed to GET

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question