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 467 forks source link

Does autocomplete-light supports 'through' relations? #511

Open pbassut opened 9 years ago

pbassut commented 9 years ago

Let's say I have the following models:

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

I'm getting the error

AttributeError at /admin/core/group/1/
Cannot set values on a ManyToManyField which specifies an intermediary model.  Use core.Membership's Manager instead.

And this is exactly what I doing:

autocomplete_light.register(Membership,
    search_fields=['^person__name'],
    attrs={
        'placeholder': 'Person',
        'data-autocomplete-minimum-characters': 3,
    },
    widget_attrs={
        'data-widget-maximum-values': 200,
        'class': 'modern-style',
    },
)

And here's the form I'm using on django admin:

class GroupForm(autocomplete_light.ModelForm):
    members = autocomplete_light.ModelMultipleChoiceField("MembershipAutocomplete")

    class Meta:
        model = Group
        exclude = ()

I've searched the docs to find out something about the through arg, but there was nothing there. Can I create an autocomplete for the Group model and have it working on the Django admin site?

jpic commented 9 years ago

I'm sure it does !

Le jeu. 8 oct. 2015 08:45, Patrick Bassut notifications@github.com a écrit :

Let's say I have the following models:

class Person(models.Model): name = models.CharField(max_length=128)

def __str__(self):              # __unicode__ on Python 2
    return self.name

class Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField(Person, through='Membership')

def __str__(self):              # __unicode__ on Python 2
    return self.name

class Membership(models.Model): person = models.ForeignKey(Person) group = models.ForeignKey(Group) date_joined = models.DateField() invite_reason = models.CharField(max_length=64)

Can I create an autocomplete for the Group model and have it working on the Django admin site?

— Reply to this email directly or view it on GitHub https://github.com/yourlabs/django-autocomplete-light/issues/511.

pbassut commented 9 years ago

Cool. Any idea how? Because I'm getting the mentioned error there

jpic commented 9 years ago

Full traceback please ! I'm already trying to make a test case BTW

pbassut commented 9 years ago

Thanks for your time. This currently is holding me to do a new release since we can't release without autocomplete because there's too many models in that many to many relation.

Environment:

Request Method: POST
Request URL: http://127.0.0.1:8000/admin/core/course/1/

Django Version: 1.7.3
Python Version: 2.7.10
Installed Applications:
('django.contrib.sites',
 'django.contrib.auth',
 'polymorphic',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'suit',
 'autocomplete_light',
 'django.contrib.admin',
 'core',
 'easy_thumbnails',
 'django_extensions',
 'mathfilters',
 'rest_framework',
 'djcelery',
 'async',
 'ckeditor',
 'ckeditor_uploader',
 'tests')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware')

Traceback:
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/django/contrib/admin/options.py" in wrapper
  583.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  105.                     response = view_func(request, *args, **kwargs)
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  52.         response = view_func(request, *args, **kwargs)
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
  206.             return view(request, *args, **kwargs)
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/django/contrib/admin/options.py" in change_view
  1456.         return self.changeform_view(request, object_id, form_url, extra_context)
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
  29.             return bound_func(*args, **kwargs)
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  105.                     response = view_func(request, *args, **kwargs)
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
  25.                 return func.__get__(self, type(self))(*args2, **kwargs2)
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/django/db/transaction.py" in inner
  394.                 return func(*args, **kwargs)
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/django/contrib/admin/options.py" in changeform_view
  1405.                 self.save_related(request, form, formsets, not add)
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/django/contrib/admin/options.py" in save_related
  1067.         form.save_m2m()
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/autocomplete_light/forms.py" in _
  171.                 old_m2m()
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/django/forms/models.py" in save_m2m
  100.                 f.save_form_data(instance, cleaned_data[f.name])
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/django/db/models/fields/related.py" in save_form_data
  2295.         setattr(instance, self.attname, data)
File "/Users/patrickbassut/Programming/logus/lib/python2.7/site-packages/django/db/models/fields/related.py" in __set__
  1183.             raise AttributeError("Cannot set values on a ManyToManyField which specifies an intermediary model.  Use %s.%s's Manager instead." % (opts.app_label, opts.object_name))

Exception Type: AttributeError at /admin/core/course/1/
Exception Value: Cannot set values on a ManyToManyField which specifies an intermediary model.  Use core.CourseTopic's Manager instead.
pbassut commented 9 years ago

Did you have the time to take a look a this? If so, could you report what you found out so far so I can help provide a solution?

jpic commented 9 years ago

Well I started in the tmtm branch, commit c80394a but I couldn't reproduce it. Could you complete this please ?

Once we have a live example in test_project, it'll be easy to add a proper test case and I can take it from there in a while.

Thanks for the report bro !!

pbassut commented 9 years ago

Give me a few hours to get this exception on your test project. I'll have to move a little bit of my code there. I'll also double check if I'm not doing something wrong to not waste your time.

pbassut commented 9 years ago

Never mind, I got it working. I went ahead of myself and tried to create an autocomplete and might have messed it up on the way.

My only problem now which I'm not sure is related to autocomplete-light is how to only show items that was not added yet.

Any idea?

pbassut commented 9 years ago

Though another problem came up. I'll open another issue for that.