Django-jet: Autocomplete with Custom queryset

Created on 26 Nov 2016  路  35Comments  路  Source: geex-arts/django-jet

In docs, its mentioned that -

Autocomplete is nice, but sometimes you don鈥檛 want this behaviour (e.x. because you want to limit the provided queryset for a particular widget). In this case you can disable autocompletion.

Then how to deal with large tables, with custom queryset. How are you handling this issue ? Is there any workaround for this ?

Edit:
I tried to use django autocomplete light for autocompletion with custom queryset. But it's showing two select dropdown widgets.
screenshot from 2016-11-27 17 46 00
How can I fix these widgets ?

Most helpful comment

@a1Gupta Do you fix this problem? I have the same problem while using django-autocomplete-light. There are two dropdown select fields, how to fix it?

All 35 comments

If you work your way through the code of Jet, you can make some overrides yourself. However, it would be good to see support included.

I propose this code as a replacement for the jet/forms.py lookup function:

`

def lookup(self):

if self.cleaned_data['q']:

    if getattr(self.model_cls, 'autocomplete_search_fields') and getattr(self.model_cls, 'autocomplete_search_query'):
        raise Exception("The model cannot have both an autocomplete_search_fields and autocomplete_search_query function.")

    elif getattr(self.model_cls, 'autocomplete_search_query'):
        qs = self.model_cls.autocomplete_search_query(self.cleaned_data['q'])

    elif getattr(self.model_cls, 'autocomplete_search_fields'):
        qs = self.model_cls.objects
        search_fields = self.model_cls.autocomplete_search_fields()
        filter_data = [Q((field + '__icontains', self.cleaned_data['q'])) for field in search_fields]
        qs = qs.filter(reduce(operator.or_, filter_data))

else:
    qs = self.model_cls.objects.none()

limit = self.cleaned_data['page_size'] or 100
page = self.cleaned_data['page'] or 1
offset = (page - 1) * limit

items = list(map(lambda instance: {
    'id': instance.pk,
    'text': get_model_instance_label(instance)
}, qs.all()[offset:offset + limit]))
total = qs.count()

return items, total

`
This way you could define a autocomplete_search_query function in your models.

@jorisvd Any idea on how to pass a queryset defined in the formfield_for_foreignkey method for that form?

Reading on jet's code, it seems that one must override the ModelLookupForm and the corresponding view, for each model to add a custom queryset, but it doesn't seems very practical.

Ideally you want support for both formfield_for_foreignkey and autocomplete_search_query as they serve different needs.
The first is often used for filtering specific to the model and field doing the linking. For example a default choice field on the example polls model would want to filter to choices belonging to the current poll.
The second is often used for generic filtering or queryset performance stuff, so soft delete support, or pulling in related tables required to construct the str representation.

@f1nality

Please come to the django-jet Discord server so we can organize if you like:

Welcome! 馃槃

I am using formfield_for_foreignkey in modeladmin to create custom queryset but it's not reflecting on autocomplete as the lookup is fetching all records.

@joristdma Your solution looks promised but little bit confuse as making changes directly on the library isn't a good idea so is there any way where I can override this functionality. Thanks

@abdulwahid24 I would like to make some pull requests but is this repository still being maintained? I am not seeing any new releases. If the author can comment he is alive then I can make PR's.

@joristdma I do agree with you. I checked there FB, Linkedin, Github but they are not active for last couple of months.

@abdulwahid24 I sent out a message through the contact form on the commercial website. No reply.

@abdulwahid24 @joristdma Can you make a PR in jet_community fork?

Hi @joristdma, I checked the above fork but its release version is very behind to the original one.

@abdulwahid24 @SalahAdDin Does it make sense to create yet another fork? Will we be able to maintain it? If someone wants to organize the new fork and edit the README and maybe some configuration files, I can make the PR's for a couple of features and bugs.

@joristdma These fork is our fork, make your PR and we will review it and merge it, if you want mantain it, your welcome.

@SalahAdDin Are you maintaining geex-arts/django-jet original repo? If yes then I would suggest you to be more active because there are people who are investing their effort in order to improve the django-jet but no is responding to accept their PR and issues.

@abdulwahid24 As I understand from @SalahAdDin reply he is mantaining jet-community/django-jet fork. I think he is open to PRs/Issues down in jet-community/django-jet.

@SalahAdDin I see the release version on jet-community/django-jet is very behind as compare to the parent repo, I am not sure whether jet-community/django-jet has all previous features and fixes from the parent repo.

@SalahAdDin I think your fork is not up to date as its not supporting django 1.11 as I am getting the below error.
File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/django/conf/urls/__init__.py", line 50, in include urlconf_module = import_module(urlconf_module) File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/importlib/__init__.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 994, in _gcd_import File "<frozen importlib._bootstrap>", line 971, in _find_and_load File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 665, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 678, in exec_module File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/jet/urls.py", line 2, in <module> from django.conf.urls import patterns, url ImportError: cannot import name 'patterns'

@abdulwahid24 these version is very ahead, is updated, many PR was merged, and etc.
Leave me see about this problem, because i think we did solved these problems before.

Can you see @abdulwahid24 https://github.com/jet-community/django-jet/blob/master/jet/urls.py?
You have to install it from github.

@SalahAdDin I installed from the release tag (https://github.com/jet-community/django-jet/archive/0.1.5.zip) like pip install https://github.com/jet-community/django-jet/archive/0.1.5.zip and then I am getting the below mentioned error.

Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x7f17de10f048>
Traceback (most recent call last):
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/django/utils/autoreload.py", line 228, in wrapper
    fn(*args, **kwargs)
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/django/core/management/commands/runserver.py", line 125, in inner_run
    self.check(display_num_errors=True)
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/django/core/management/base.py", line 359, in check
    include_deployment_checks=include_deployment_checks,
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/django/core/management/base.py", line 346, in _run_checks
    return checks.run_checks(**kwargs)
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/django/core/checks/registry.py", line 81, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/django/core/checks/urls.py", line 16, in check_url_config
    return check_resolver(resolver)
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/django/core/checks/urls.py", line 26, in check_resolver
    return check_method()
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/django/urls/resolvers.py", line 254, in check
    for pattern in self.url_patterns:
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/django/urls/resolvers.py", line 405, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/django/urls/resolvers.py", line 398, in urlconf_module
    return import_module(self.urlconf_name)
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/abdulw/workspace/SynDashboard/SynDashboard/urls.py", line 27, in <module>
    url(r'^jet/', include('jet.urls', 'jet')),
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/django/conf/urls/__init__.py", line 50, in include
    urlconf_module = import_module(urlconf_module)
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/abdulw/workspace/SynDashboard/.env/lib/python3.6/site-packages/jet/urls.py", line 2, in <module>
    from django.conf.urls import patterns, url
ImportError: cannot import name 'patterns'

Ok, because these release is old, we didn't release a new version yet. You have to install from master branch. Maybe the documentation is wrong now.

Then I install by pip install git+https://github.com/jet-community/django-jet.git, Its working fine.
Now I think @joristdma you should submit your PRs on jet-community's django-jet

@abdulwahid24 I'm glad to hear it.

@joristdma Any update about your PRs request on jet-community's django-jet

@joristdma @abdulwahid24 I'm waiting for it.

@abdulwahid24 @SalahAdDin No, I didn't proceed because there doesn't seem to be any fork which is up-to-date and properly maintained?

@joristdma I think this fork https://github.com/jet-community/django-jet is up-to-date as @SalahAdDin is maintaining it.

Yes, i'm trying.

@SalahAdDin I would request you to make the latest release because everyone looks at last release on your fork.

I'll try to make those changes within 2 weeks or so. @SalahAdDin if you find the time, maybe you can update the repo to the latest version by then.

@SalahAdDin @abdulwahid24 I implemented this feature in a new fork from the latest master of django-jet. You can find the repo here: https://github.com/tityrus/django-jet . Master branch. You can find more info in the last few commit messages there. Basically it works like this: in your model, instead of the autocomplete_search_fields, create a method autocomplete_search_query that returns a queryset. The arguments passed to the function are the search query string and the user object. So your function definition can be: def autocomplete_search_query(self, q, user):.

@tityrus @SalahAdDin I see Django 2.0 added support for autocomplete_fields

@abdulwahid24 Really?

@a1Gupta Do you fix this problem? I have the same problem while using django-autocomplete-light. There are two dropdown select fields, how to fix it?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andreamanni picture andreamanni  路  4Comments

a1Gupta picture a1Gupta  路  7Comments

seenu4linux picture seenu4linux  路  3Comments

uroybd picture uroybd  路  5Comments

mapleflow picture mapleflow  路  8Comments