InterSIS / django-rest-encrypted-lookup

Replace Rest Framework's IntegerField pk or id lookups with encrypted strings.
GNU General Public License v3.0
27 stars 8 forks source link

using id with filter_class #14

Open whoisearth opened 8 years ago

whoisearth commented 8 years ago

I'm attempting to use a django filter while continuing using the encrypted id.

I can do this -

http://localhost:8000/api/v1/widget/?id=3

but I can't do this -

http://localhost:8000/api/v1/widget/?id=zspnn6wva2rd47z44jo65bi6iy

doing so generates the following error:

invalid literal for int() with base 10: 'zspnn6wva2rd47z44jo65bi6iy'

which makes sense because it's expecting an integer.

I'm using django-filter like so:

class WidgetFilter(django_filters.FilterSet):
    id = django_filters.CharFilter(name='id', lookup_type='exact')
    name = django_filters.CharFilter(name='username', lookup_type='exact')
    list = django_filters.CharFilter(name='list__name', lookup_type='exact')

    class Meta:
        model = Widget
        fields = ['id', 'username', 'list__name']

When I query the actual ID it does return the encrypted value and I can query like this:

http://localhost:8000/api/v1/widget/zspnn6wva2rd47z44jo65bi6iy/

JASchilz commented 8 years ago

Understood! It's been a while since I've touched this, so I might be a little dusty.

If I'm seeing it correctly, there's a failure of the two plugins to work together as opposed to a failure of this plugin. It looks like DRF Encrypted Lookup lives above the ORM level; it lives at the serializer and view level. And my guess is that django-filter bypasses these and reaches directly into the ORM level. So I'll label the issue as an enhancement or a question.

The easiest thing for you to do might be to modify the ID as it comes in, inside your filter class. You could use the get_cipher method of your DRF Encrypted Lookup Serializer. Then you can use the cipher's encode and decode methods--see utils.py--to turn zspnn6wva2rd47z44jo65bi6iy into 3.

If it works, let me know the code! The django-filter library looks like one I might want to use.