farhan0581 / django-admin-autocomplete-filter

A simple Django app to render list filters in django admin using autocomplete widget.
GNU General Public License v3.0
351 stars 75 forks source link

model_admin'. as_view only accepts arguments that are already attributes of the class #60

Open adontz opened 3 years ago

adontz commented 3 years ago

Django==3.2.2 django-admin-autocomplete-filter==0.6.1

After upgrading from Django==3.1.5 I receive

CustomFilterView() received an invalid keyword 'model_admin'. as_view only accepts arguments that are already attributes of the class.

For the following code

class MyModelAdmin(admin.ModelAdmin):
...
    def get_urls(self):
        base_urls = super().get_urls()
        filter_urls = [
            path(
                'filter-autocomplete/',
                self.admin_site.admin_view(CustomFilterView.as_view(model_admin=self)),
                name='authnz_custom_filter_autocomplete'),
        ]

        return filter_urls + base_urls
adontz commented 3 years ago

@farhan0581 is this project supported yet?

farhan0581 commented 3 years ago

can you try using the new version 0.7 ?

th-thomas commented 3 years ago

Same issue but with Django 3.2.3 and version 0.7

bboru21 commented 3 years ago

@adontz and @th-thomas -

Looks like Django introduced validation on View attributes within the as_view method: https://github.com/django/django/blob/main/django/views/generic/base.py#L56-L59

I think adding model_admin as an attribute to the CustomFilterView should get it to pass that validation and get it working for you:

class CustomFilterView(AutocompleteJsonView):

    model_admin = None

    def get_queryset(self):
        qs = Model.objects.all()
        if self.term:
            # apply limiting logic here
            qs = qs.filter(foo__istartswith=self.term)
        return qs
tatterdemalion commented 3 years ago

Adding model_admin = None fails because of this line: https://github.com/farhan0581/django-admin-autocomplete-filter/blob/pre_release/admin_auto_filters/views.py#L17

self.paginator_class = self.model_admin.paginator

I overcame this by setting base model admin class admin.ModelAdmin and changing get_paginator method:

class CustomFilterView(AutocompleteJsonView):
    model_admin = admin.ModelAdmin

    def get_paginator(self, *args, **kwargs):
        return self.paginator_class(*args, **kwargs)

I know this is a stupid workaround but seems to get the job done.

creshal commented 2 years ago

I tried this workaround, and while it makes Django run without errors, it always returns empty result sets, even if I don't override get_queryset at all. Something still seems broken.

edu2004eu commented 2 years ago

For those still struggling with this, I've found a workaround. You will need to override the get method on the custom search view:

def get(self, request, *args, **kwargs):
    self.term, self.model_admin, self.source_field, to_field_name = self.process_request(request)

    return super().get(request, *args, **kwargs)
shaig-planetly commented 2 years ago

@edu2004eu this causes a 403 error

ashishnitinpatil commented 1 year ago

I had to do something hacky in order to resolve all issues & get the view to work correctly -

class CustomFilterView(AutocompleteJsonView):
    model_admin = MyAdmin #  using my final class; can get away with None as well

    def get_queryset(self):
        # overriding to fix Django 3.2 upgrade issue (removed self.complex_query line)
        qs = self.model_admin.get_queryset(self.request)
        qs, search_use_distinct = self.model_admin.get_search_results(
            self.request, qs, self.term
        )
        # qs = qs.filter() -> my custom search
        if search_use_distinct:
            qs = qs.distinct()
        return qs

I'm using the code from the PR https://github.com/farhan0581/django-admin-autocomplete-filter/pull/78

cash commented 1 year ago

The commit in Django 3.2 that broke this package is here: https://github.com/django/django/commit/3071660acfbdf4b5c59457c8e9dc345d5e8894c5

From Django developers' perspective, AutocompleteJsonView is private because it is not documented so they can change it without deprecation.

I think many uses cases can be handled by this package: https://github.com/demiroren-teknoloji/django-admin-autocomplete-list-filter