yourlabs / django-autocomplete-light

A fresh approach to autocomplete implementations, specially for Django. Status: v4 alpha, v3 stable, v2 & v1 deprecated.
https://django-autocomplete-light.readthedocs.io
MIT License
1.8k stars 468 forks source link

Inline autocomplete breaking #452

Closed symbiosdotwiki closed 9 years ago

symbiosdotwiki commented 9 years ago

I have no real idea why this would be breaking, I am just using a simple autocomplete in an inline and getting this error

missing FROM-clause entry for table "subjects_subject"
LINE 1: SELECT (CASE WHEN Subjects_subject.id='1' THEN 0 END) AS "or...

any help is appreciate, here is traceback

Environment:

Request Method: POST
Request URL: http://104.236.221.79/admin/Tutor/tutorstudentrelationship/12/

Django Version: 1.8.2
Python Version: 2.7.6
Installed Applications:
('autocomplete_light',
 'favicon',
 'wpadmin',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.sites',
 'apptemplates',
 'jquery',
 'crispy_forms',
 'bootstrap3',
 'localflavor',
 'datetimewidget',
 'fm',
 'django_fsm',
 'fsm_admin',
 'djwkhtmltopdf',
 'schedule',
 'easymoney',
 'phonenumber_field',
 'django_countries',
 'postal',
 'babel',
 'easy_thumbnails',
 'timezone_field',
 'allauth',
 'allauth.account',
 'allauth.socialaccount',
 'Accounting',
 'Billing',
 'GroupInvitations',
 'BrownstoneTutors',
 'Sessions',
 'Student',
 'Tutor',
 'Client',
 'Subjects')
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',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.locale.LocaleMiddleware')

Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in wrapper
  616.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
  110.                     response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func
  57.         response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/sites.py" in inner
  233.             return view(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in change_view
  1519.         return self.changeform_view(request, object_id, form_url, extra_context)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapper
  34.             return bound_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
  110.                     response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in bound_func
  30.                 return func.__get__(self, type(self))(*args2, **kwargs2)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in inner
  145.                     return func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in changeform_view
  1466.             if all_valid(formsets) and form_validated:
File "/usr/local/lib/python2.7/dist-packages/django/forms/formsets.py" in all_valid
  439.         if not formset.is_valid():
File "/usr/local/lib/python2.7/dist-packages/django/forms/formsets.py" in is_valid
  304.         self.errors
File "/usr/local/lib/python2.7/dist-packages/django/forms/formsets.py" in errors
  278.             self.full_clean()
File "/usr/local/lib/python2.7/dist-packages/django/forms/formsets.py" in full_clean
  327.             self._errors.append(form.errors)
File "/usr/local/lib/python2.7/dist-packages/django/forms/forms.py" in errors
  176.             self.full_clean()
File "/usr/local/lib/python2.7/dist-packages/django/forms/forms.py" in full_clean
  392.         self._clean_fields()
File "/usr/local/lib/python2.7/dist-packages/django/forms/forms.py" in _clean_fields
  407.                     value = field.clean(value)
File "/usr/local/lib/python2.7/dist-packages/django/forms/fields.py" in clean
  163.         self.validate(value)
File "/usr/local/lib/python2.7/dist-packages/autocomplete_light/fields.py" in validate
  61.         if value and not self.autocomplete(values=values).validate_values():
File "/usr/local/lib/python2.7/dist-packages/autocomplete_light/autocomplete/model.py" in validate_values
  169.         return len(self.choices_for_values()) == len(self.values)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py" in __len__
  144.         self._fetch_all()
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py" in _fetch_all
  965.             self._result_cache = list(self.iterator())
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py" in iterator
  238.         results = compiler.execute_sql()
File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py" in execute_sql
  840.             cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py" in execute
  79.             return super(CursorDebugWrapper, self).execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/django/db/utils.py" in __exit__
  97.                 six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

Exception Type: ProgrammingError at /admin/Tutor/tutorstudentrelationship/12/
Exception Value: missing FROM-clause entry for table "subjects_subject"
LINE 1: SELECT (CASE WHEN Subjects_subject.id='1' THEN 0 END) AS "or...
```                          ^
jpic commented 9 years ago

Could you provide more information so that we can reproduce ? Maybe isolate the bug in a new app in the test_project so that we can work on it ? Thanks !

symbiosdotwiki commented 9 years ago

@jpic Its really just the basic example:

#models.py
class Subject(models.Model):
    subject_type = models.ForeignKey(SubjectType)
    name = models.CharField(max_length = 100)

    def __unicode__(self):
        return unicode(self.subject_type) + ": " + unicode(self.name)
#autocomplete_light_registry.py
import autocomplete_light
from models import Subject

class SubjectAutocomplete(autocomplete_light.AutocompleteModelBase):
    search_fields = ['name',]
autocomplete_light.register(Subject)
#admin.py
import autocomplete_light
autocomplete_light.autodiscover()
............
class TutorStudentSubjectRateInline(admin.TabularInline):
    model = TutorStudentSubjectRate
    extra = 0
    form = autocomplete_light.modelform_factory(TutorStudentSubjectRate, fields = '__all__')
symbiosdotwiki commented 9 years ago

the autocomplete works fine, but it can't be saved once you choose the thing

symbiosdotwiki commented 9 years ago

also the expanded traceback:

/usr/local/lib/python2.7/dist-packages/django/db/utils.py in __exit__
                            six.reraise(dj_exc_type, dj_exc_value, traceback) ...
▼ Local vars
Variable    Value
self    
<django.db.utils.DatabaseErrorWrapper object at 0x7f8aa2d81810>
traceback   
<traceback object at 0x7f8aa2c8ccf8>
exc_type    
<class 'psycopg2.ProgrammingError'>
dj_exc_type 
<class 'django.db.utils.ProgrammingError'>
dj_exc_value    
ProgrammingError('missing FROM-clause entry for table "subjects_subject"\nLINE 1: SELECT (CASE WHEN Subjects_subject.id=\'3\' THEN 0 END) AS "or...\n                          ^\n',)
exc_value   
ProgrammingError('missing FROM-clause entry for table "subjects_subject"\nLINE 1: SELECT (CASE WHEN Subjects_subject.id=\'3\' THEN 0 END) AS "or...\n                          ^\n',)
db_exc_type 
<class 'psycopg2.ProgrammingError'>
/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py in execute
                            return self.cursor.execute(sql, params) ...
▼ Local vars
Variable    Value
self    
<django.db.backends.utils.CursorDebugWrapper object at 0x7f8aa2c81c10>
params  
(3,)
sql 
u'SELECT (CASE WHEN Subjects_subject.id=\'3\' THEN 0 END) AS "ordering", "Subjects_subject"."id", "Subjects_subject"."subject_type_id", "Subjects_subject"."name" FROM "Subjects_subject" WHERE "Subjects_subject"."id" IN (%s) ORDER BY "ordering" ASC'
symbiosdotwiki commented 9 years ago

I get the same error for basic Admin for the same model as well

jpic commented 9 years ago

Could you fix formating of your comments please ? Thanks

https://guides.github.com/features/mastering-markdown/

symbiosdotwiki commented 9 years ago

@jpic all fixed, sorry.

I literally followed the super basic first example to just register a model and autocomplete in another model's admin, I don't know why I am getting sql errors...

symbiosdotwiki commented 9 years ago

Any news on this?

jpic commented 9 years ago

Ok, you meant you "all fixed" the formatting only ^^

What PG version is this ?

I understand from the error that there is a reference to the subjects_subject table which fails because in the FROM clause we're selecting from the Subjects_subject table. However, I don't see where the query is referring to subjects_subject, all I can see apparently is reference to Subjects_subject which is appropriately in the FROM clause:

u'SELECT (CASE WHEN Subjects_subject.id=\'3\' THEN 0 END) AS "ordering", "Subjects_subject"."id", "Subjects_subject"."subject_type_id", "Subjects_subject"."name" FROM "Subjects_subject" WHERE "Subjects_subject"."id" IN (%s) ORDER BY "ordering" ASC'

Maybe it's converting the first one, Subjects_subject from the CASE WHEN to lowercase. Could you try this query and report what happens ? Does it work better with "Subjects_subject"."id" instead of Subjects_subject.id (note the absence of double quote ").

Thanks !

jpic commented 9 years ago

Confirmed, that really seems to be the bug:

jpic=> create table "Bar" ( id int primary key, name varchar (100));
CREATE TABLE
jpic=> select Bar.id from "Bar";
ERROR:  missing FROM-clause entry for table "bar"
LINE 1: select Bar.id from "Bar";
               ^
jpic=> select "Bar".id from "Bar";
┌────┐
│ id │
├────┤
└────┘
(0 rows)
jpic commented 9 years ago

Closing in favor of PR #452, please review it and let us know if it works for you. Thanks !

symbiosdotwiki commented 9 years ago

Awesome! I'm glad my terrible naming practices helped to find such a strange case.

This would have taken me forever to find/fix, thanks!

jpic commented 9 years ago

Thanks for the kind words, I'm a bit anal about naming myself so maybe that did help xD

PR in question is #464, not #452.

jpic commented 9 years ago

Fix released in 2.2.5