Opened 20 years ago
Closed 12 years ago
#25 closed Bug (fixed)
Filtering interface on ForeignKey <select> boxes
| Reported by: | Adrian Holovaty | Owned by: | nobody |
|---|---|---|---|
| Component: | contrib.admin | Version: | dev |
| Severity: | Normal | Keywords: | feature |
| Cc: | rokclimb15@…, eppsilon, Victor Hooi | Triage Stage: | Accepted |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | yes |
| Easy pickings: | no | UI/UX: | yes |
Description
Select boxes are a pain, and slow, to deal with when there are a lot of values to select from. (Example: datelines on news stories). There should be a generator option, use_filter_interface, available on select boxes. It would add an <input type="text"> next to the select box and allow users to filter the select box that way.
This would make data entry quicker, because folks could just paste in the dateline they want, and it'd be selected for them (assuming it's been entered as a dateline in the system).
Attachments (7)
Change History (42)
comment:1 by , 20 years ago
| milestone: | → Version 1.1 |
|---|
comment:2 by , 20 years ago
| priority: | normal → low |
|---|
comment:3 by , 20 years ago
| Type: | defect → enhancement |
|---|
comment:4 by , 19 years ago
comment:5 by , 19 years ago
| Triage Stage: | Unreviewed → Design decision needed |
|---|
Or even a javascript textbox+dropdown that filters entries as you type.
comment:6 by , 18 years ago
| Triage Stage: | Design decision needed → Accepted |
|---|
comment:7 by , 17 years ago
| milestone: | → post-1.0 |
|---|
Marking as post-1.0 as this is not essential for 1.0.
comment:9 by , 15 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
I'm going to give this a go at the DjangoCon sprint.
comment:10 by , 15 years ago
| Has patch: | set |
|---|---|
| milestone: | → 1.3 |
| Version: | → SVN |
comment:11 by , 15 years ago
I've got something workable. Screenshot and sample patch attached (I'll be submitting through a GitHub pull request). Some notes:
- It's very slow in large (5000+) sets. Once my changes are applied, I will file another ticket in which I make some performance improvements. I will be porting those performance enhancements (which will change the behavior) to filter_horizontal and filter_vertical as well, for consistency.
- I used jQuery for the new widget, per Jannis in #django-dev.
- Tested in IE + Mac browsers.
- Test and docs included.
If I get a thumbs-up, I'll submit a pull request on GitHub.
comment:12 by , 15 years ago
| Summary: | Allow use_filter_interface on non-multiple select boxes → Filtering interface on ForeignKey <select> boxes |
|---|
comment:14 by , 15 years ago
This looks like great work. I haven't taken a look at the code yet, but I will check it out during the sprints tomorrow. I'd like to see this get into core soon, as it looks damn useful.
comment:15 by , 15 years ago
| Cc: | added |
|---|
comment:16 by , 15 years ago
Sorry I didn't comment earlier. I looked at this during the sprints, and the code looks good. However, I'm not too comfortable with my javascript abilities, so I didn't want to mark it RFC without knowing it would work across browsers & such.
comment:17 by , 15 years ago
| Cc: | added |
|---|
comment:18 by , 15 years ago
| Keywords: | feature added |
|---|
comment:19 by , 15 years ago
| Cc: | added |
|---|
heya,
Just thought I'd chime in that this is awesome =). Can't wait for this to hit trunk - hopefully it'll be soon...haha...any word on that?
Cheers,
Victor
comment:20 by , 15 years ago
| Patch needs improvement: | set |
|---|
Victor:
It won't hit in it's current state. The patch needs a fair amount of cleaning up:
- it doesn't apply to trunk (tests have recently been migrated to unittests)
- it hard codes a path to '/media'
- documentation needs to be wrapped to 80 chars
Plus we definitely need some more info about compatibility with different browsers - what versions of Firefox, Internet Explorer, Safari, Chrome and Opera does it work on? From the look of the patch, and having implemented similar things before, the use of jQuery should prevent a lot of problems, but it is very easy for this kind of thing to break in some browsers, or be unusable slow etc.
cpharmston: I'm not sure what kind of thumbs up you are looking for. Since the ticket already exists, it will be easiest just to keep an updated ticket here. Once it is ready, any committer will then be able to commit.
comment:21 by , 15 years ago
Another thing - I personally would drop the 'Available' header - that makes sense for the m2m selects where you have 'Available' and 'Selected', but here it just seems to add vertical space.
comment:22 by , 15 years ago
This is painfully slow for me right now. I tested this on Chrome 9.x with 2000 objects named "user". After typing in "user" in the filter it took about 3-5 seconds to refresh (on a quite fast machine). Most of the time is spent on re-creating the <option> elements one-by-one. Creating all the HTML in one shot could improve this. Not creating elements again would be probably even better (i.e. keep the option elements in the cache).
comment:23 by , 15 years ago
heya,
Hmm, that's strange - the Github repository seems to 404 for me. And the cpharmston's user page doesn't exist?
https://github.com/cpharmston/
According to http://status.github.com/, Github is up and fine.
cpharmston - did you change your Github username or something?
Also, I'm curious how people think this compares to the from django-extensions:
http://code.google.com/p/django-command-extensions/
Screenshot:
http://www.flickr.com/photos/msgre/3524424961/
To be honest, I like the solution from cpharmston better, with the select box and search filter. Seems much more usable/intuitive, and also fits better with the rest of the Django admin.
Cheers,
Victor
comment:25 by , 15 years ago
heya,
Is there any word on this patch, or anybody willing to adopt it?
From a usability POV, I think a patch like this is incredibly useful in the Django admin, particularly when the number of FK's grow large (which they invariably do).
Just like the filter_horizontal select widget, it definitely adds a lot of polish.
Anyhow, I just tried cpharmstron's patch against trunk, when I attempt to use it on an Add form I get:
'str' object has no attribute 'copy'
The full stacktrace:
Environment:
Request Method: GET
Request URL: http://nextgen.victorhooi.com/admin/conferences/attendance/add/
Django Version: 1.3 beta 1 SVN-15400
Python Version: 2.6.6
Installed Applications:
['django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'allocations',
'conferences',
'facilities',
'nextgensite',
'people',
'django_extensions',
'reversion',
'south',
'debug_toolbar']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'debug_toolbar.middleware.DebugToolbarMiddleware')
Traceback:
File "/sites/.virtualenvs/colloquium/src/django/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/sites/.virtualenvs/colloquium/src/django/django/contrib/admin/options.py" in wrapper
312. return self.admin_site.admin_view(view)(*args, **kwargs)
File "/sites/.virtualenvs/colloquium/src/django/django/utils/decorators.py" in _wrapped_view
93. response = view_func(request, *args, **kwargs)
File "/sites/.virtualenvs/colloquium/src/django/django/views/decorators/cache.py" in _wrapped_view_func
79. response = view_func(request, *args, **kwargs)
File "/sites/.virtualenvs/colloquium/src/django/django/contrib/admin/sites.py" in inner
190. return view(request, *args, **kwargs)
File "/sites/.virtualenvs/colloquium/src/django/django/utils/decorators.py" in _wrapper
28. return bound_func(*args, **kwargs)
File "/sites/.virtualenvs/colloquium/src/django/django/utils/decorators.py" in _wrapped_view
93. response = view_func(request, *args, **kwargs)
File "/sites/.virtualenvs/colloquium/src/django/django/utils/decorators.py" in bound_func
24. return func(self, *args2, **kwargs2)
File "/sites/.virtualenvs/colloquium/src/django/django/db/transaction.py" in inner
282. res = func(*args, **kwargs)
File "/sites/.virtualenvs/colloquium/src/django/django/contrib/admin/options.py" in add_view
852. ModelForm = self.get_form(request)
File "/sites/.virtualenvs/colloquium/src/django/django/contrib/admin/options.py" in get_form
437. return modelform_factory(self.model, **defaults)
File "/sites/.virtualenvs/colloquium/src/django/django/forms/models.py" in modelform_factory
400. return ModelFormMetaclass(class_name, (form,), form_class_attrs)
File "/sites/.virtualenvs/colloquium/src/django/django/forms/models.py" in __new__
206. opts.exclude, opts.widgets, formfield_callback)
File "/sites/.virtualenvs/colloquium/src/django/django/forms/models.py" in fields_for_model
164. formfield = formfield_callback(f, **kwargs)
File "/sites/.virtualenvs/colloquium/src/django/django/utils/functional.py" in _curried
55. return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs))
File "/sites/.virtualenvs/colloquium/src/django/django/contrib/admin/options.py" in formfield_for_dbfield
106. formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
File "/sites/.virtualenvs/colloquium/src/django/django/contrib/admin/options.py" in formfield_for_foreignkey
167. db_field.verbose_name, (db_field.name in self.filter_vertical))
File "/sites/.virtualenvs/colloquium/src/django/django/forms/widgets.py" in __init__
505. super(Select, self).__init__(attrs)
File "/sites/.virtualenvs/colloquium/src/django/django/forms/widgets.py" in __init__
147. self.attrs = attrs.copy()
Exception Type: AttributeError at /admin/conferences/attendance/add/
Exception Value: 'str' object has no attribute 'copy'
Any ideas?
Cheers,
Victor
by , 15 years ago
| Attachment: | select_filter.diff added |
|---|
I modified the previous patch and made it more efficient. Still needs to be tested in browsers other than FF and Chrome.
comment:26 by , 15 years ago
| Owner: | changed from to |
|---|---|
| Status: | assigned → new |
I added tests and documentation to the patch. One thing to note is that the previous patch required a fk_filter attribute on the ModelAdmin class to specify which foreignkey fields are rendered using the new filter interface. In this patch, you simply specify which foreignkey field needs the filtering interface in the ModelAdmin filter_vertical list.
by , 15 years ago
| Attachment: | select_filter.2.diff added |
|---|
fixed a bug. Development can be found at https://github.com/sebleier/django/tree/feature/select-filter
by , 15 years ago
| Attachment: | select_filter.3.diff added |
|---|
fixed a bug. Development can be found at https://github.com/sebleier/django/tree/feature/select-filter
comment:27 by , 15 years ago
| Severity: | minor → Normal |
|---|---|
| Type: | enhancement → New feature |
comment:28 by , 14 years ago
| UI/UX: | set |
|---|
comment:29 by , 14 years ago
| Easy pickings: | set |
|---|
comment:30 by , 14 years ago
heya,
Any update on how close this is to hitting trunk?
I mean, it's flagged "Easy pickings" by Idan *grins*, so surely it's close, right? Are there any showstopppers?
Cheers,
Victor
Btw, I also saw this:
http://harvesthq.github.com/chosen/
Chosen's a JQuery (or Prototype) plugin that basically similar combo-box support, but without the scrollable list underneath.
comment:31 by , 14 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
| Type: | New feature → Bug |
comment:32 by , 14 years ago
| Owner: | changed from to |
|---|---|
| Status: | assigned → new |
I'm currently trying to adapt sebleier's work for Django 1.4.
Not sure who set the owner to anonymous, but I'm claiming this. (Apologies if this is bad form.)
comment:33 by , 14 years ago
| Owner: | changed from to |
|---|
I'd like to surrender this ticket. As a relative newcomer to Django, I can't figure out whether this solution (sebleier's patch) belongs in Django 1.4, which already has raw-ID fields and select-filter widgets for this kind of user experience.
by , 14 years ago
| Attachment: | select_filter_for_Django_1_4.diff added |
|---|
Attempted migration to Django 1.4 (un-tested! and possibly not useful :)
comment:34 by , 13 years ago
| Easy pickings: | unset |
|---|
comment:35 by , 12 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
I think raw_id_fields is answer for this ticket and thus it should be closed as already solved.
Milestone Version 1.1 deleted