make "Add another" popup work

413 views
Skip to first unread message

Raik Grünberg

unread,
Aug 27, 2013, 7:02:00 PM8/27/13
to django-s...@googlegroups.com
Hi there,

I have implemented a AutoCompleteSelectedField for selecting a ForeignKey related object in a django.admin form. Now I would like to add the nice little green "Plus" button that allows the user to directly add a new object of this type and then come back to the original form. According to the django-selectable manual, this should be possible (Quote):

"
The django-selectable widgets are compatitible with the add another popup in the admin. It’s that little green plus sign that appears next to ForeignKey or ManyToManyField items. This makes django-selectable a user friendly replacement for the ModelAdmin.raw_id_fields when the default select box grows too long.
"

Could anyone give me an example for actually getting this done? I "kind of" got this working but the problem is that my popup window is not closing and the new object is not entered into the SelectedField. So the last part of the process is going wrong. Here is what I did (simplified, leaving out bits):

****************
***models.py::

class DnaComponent(models.Model):

    name = models.CharField('Name', max_length=200, blank=True)
    displayId = models.CharField('ID', max_length=20, unique=True)

    insert = models.ForeignKey( 'self', blank=True, null=True, related_name='Insert')

...

***************
***forms.py::

from selectable.base import ModelLookup
from selectable.registry import registry
import selectable.forms as sforms

class InsertLookup(ModelLookup):
    model = DnaComponent
    search_fields = ('displayId__startswith', 'name__icontains')
   
    def get_item_id(self,item):
        return item.pk

registry.register(InsertLookup)

class DnaComponentForm(forms.ModelForm):
       
    insert = sforms.AutoCompleteSelectField(lookup_class=InsertLookup, required=False)

    class Meta:
        model = DnaComponent

***************
***admin.py::

class DnaComponentAdmin( admin.ModelAdmin ):
    form = DnaComponentForm

    def get_form(self, request, obj=None, **kwargs):
        field = form.base_fields['insert']
        if not isinstance(field.widget, RelatedFieldWidgetWrapper ):
            relation = DnaComponent._meta.get_field('insert').rel
            field.widget.choices = []  ## workaround to simulate choicefield
            field.widget = RelatedFieldWidgetWrapper( field.widget, relation, self.admin_site )

Any idea how this can be fixed?

Thanks a lot in advance,
Greetings,
Raik

Mark Lavin

unread,
Aug 27, 2013, 8:18:30 PM8/27/13
to django-s...@googlegroups.com
This is done in the example project for the Farm model which allows adding new owners (Users) and Fruit: https://bitbucket.org/mlavin/django-selectable/src/35399783605a5a1867cfb5a3c50a8efff816cfae/example/core/admin.py?at=default There are a few odd pieces in there for the owner so that it can create new owners and still pass the model validation. However the Fruit is done simply by changing the widget in the form Meta.


--
You received this message because you are subscribed to the Google Groups "django-selectable" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-selecta...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Raik Grünberg

unread,
Aug 27, 2013, 9:50:38 PM8/27/13
to django-s...@googlegroups.com
Thanks a lot for the fast response!

This looks much easier indeed. Unfortunately, it didn't work for me yet. So I just put the AutoCompleteSelectField(...allow_new=True) into the Meta.widgets of the ModelForm as you do it with Fruit in your example. RelatedFieldWidgetWrapper is indeed called automatically now but then fails in the first line of __init__:

AttributeError: 'AutoCompleteSelectField' object has no attribute 'is_hidden'

The exception goes back to this django code in widgets.py::

class RelatedFieldWidgetWrapper(forms.Widget):
    """
    This class is a wrapper to a given widget to add the add icon for the
    admin interface.
    """
    def __init__(self, widget, rel, admin_site, can_add_related=None):
        self.is_hidden = widget.is_hidden
...

The interesting thing is that I get the same error even if I set allow_new=False. But in this case, the Wrapper shouldn't be actually called, right? Any hint what could be going wrong here?

Anyway, I'll test run and dig into your example tomorrow.

Have a nice evening,
Raik
--
___________________________________
Raik Grünberg
http://www.raiks.de/contact.html
___________________________________

Mark Lavin

unread,
Aug 27, 2013, 9:55:02 PM8/27/13
to django-s...@googlegroups.com
You cannot use AutoCompleteSelectField in the Meta.widgets because it is a form field not a widget. The corresponding widget is the AutoCompleteSelectWidget or the AutoComboboxSelectWidget.

Raik Grünberg

unread,
Aug 28, 2013, 12:13:26 AM8/28/13
to django-s...@googlegroups.com
Outch, how embarrassing. Yes, that's it. And now it works like a charm.
Thanks a lot for your help.
Great project!

Raik

Julio Perez

unread,
Mar 17, 2014, 2:46:32 PM3/17/14
to django-s...@googlegroups.com
Hi,

I have a similar situation but I cannot get the plus sign for foreign key field, neither using AutoCompleteSelectWidget nor AutoCompleteSelectField

any help is highly appreciated.
Reply all
Reply to author
Forward
0 new messages