izimobil / django-rest-framework-datatables

Seamless integration between Django REST framework and Datatables.
http://django-rest-framework-datatables.readthedocs.io/en/latest/
MIT License
391 stars 89 forks source link

Addition of GlobalFilter to ModelMultipleChoiceFilter subclass causes crash #102

Open matthewhegarty opened 3 years ago

matthewhegarty commented 3 years ago

I tried to update the example application to include global search support for the YADCF column filters.

i.e. in example/album/views.py:

class YADCFModelMultipleChoiceFilter(GlobalFilter, filters.ModelMultipleChoiceFilter):
    field_class = YADCFModelMultipleChoiceField

class GlobalCharFilter(GlobalFilter, filters.CharFilter):
    pass

class GlobalNumberFilter(GlobalFilter, filters.NumberFilter):
    pass

class AlbumFilter(DatatablesFilterSet):
    artist_name = YADCFModelMultipleChoiceFilter(
        field_name="artist__name", queryset=Artist.objects.all(), lookup_expr="contains"
    )

    rank = GlobalNumberFilter()
    name = GlobalCharFilter()

    class Meta:
        model = Album
        fields = ("artist_name", )

However, the inclusion of GlobalFilter in YADCFModelMultipleChoiceFilter causes the example application to crash.

To reproduce, include the code above (example/albums/views.py), and enter a value into the multi select filter

ex1

This will cause the application to crash with:

sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type.

I suspect that this might be due to the lack of regexp support in sqlite by default.

st1.txt

izimobil commented 3 years ago

@matthewhegarty thanks for investigating, could you confirm it's really a SQLite limitation, and if so, add a note to the related documentation ? Thanks !

matthewhegarty commented 3 years ago

Yes, I'll confirm when I get a chance to check.

matthewhegarty commented 3 years ago

I tested this using postgres, and there is a different crash:

django.db.utils.ProgrammingError: can't adapt type 'Artist'

st-postgres.txt

It looks like this is happening because the generated SQL contains a lookup value which is not quoted correctly (e.g. Elvis Presley):

SELECT "albums_album"."id", "albums_album"."name", "albums_album"."rank", "albums_album"."year", "albums_album"."artist_id", "albums_artist"."id", "albums_artist"."name" 
FROM "albums_album" 
INNER JOIN "albums_artist" ON ("albums_album"."artist_id" = "albums_artist"."id") 
WHERE "albums_artist"."name"::text ~ Elvis Presley ORDER BY "albums_album"."rank" ASC

Declaring to_field_name results in a different error:

    artist_name = YADCFModelMultipleChoiceFilter(
        field_name="artist__name", queryset=Artist.objects.all(), lookup_expr="contains", to_field_name="name"
    )