django-admin-autocomplete-filter icon indicating copy to clipboard operation
django-admin-autocomplete-filter copied to clipboard

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

Open adontz opened this issue 4 years ago • 12 comments

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 avatar May 08 '21 06:05 adontz

@farhan0581 is this project supported yet?

adontz avatar Jun 09 '21 15:06 adontz

can you try using the new version 0.7 ?

farhan0581 avatar Jun 30 '21 04:06 farhan0581

Same issue but with Django 3.2.3 and version 0.7

th-thomas avatar Jul 08 '21 13:07 th-thomas

@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

bboru21 avatar Jul 21 '21 19:07 bboru21

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.

tatterdemalion avatar Jul 22 '21 08:07 tatterdemalion

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.

creshal avatar Jan 27 '22 15:01 creshal

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)

edu2004eu avatar May 17 '22 23:05 edu2004eu

@edu2004eu this causes a 403 error

shaig-planetly avatar Jun 21 '22 09:06 shaig-planetly

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

ashishnitinpatil avatar Oct 18 '22 16:10 ashishnitinpatil

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

cash avatar Nov 04 '22 15:11 cash