5

The green plus sign button for adding new instances in the admin form disappears for my MultiSelect field (photos) when I define it in my form. Ie, removing the line with the definition (photos = ...) makes the plus sign appear. However, in order to use a custom Field/Widget I need to figure this out.

class GalleryForm(ModelForm):

    photos = ModelMultipleChoiceField(queryset=Photo.objects.all(), label="Photos")

    def __init__(self, *args, **kwargs):
        super(GalleryForm, self).__init__(*args, **kwargs)

I've peeked at the Django source code and it seems like I have to wrap my widget in a RelatedFieldWidgetWrapper, but I haven't quite gotten my head around it. Any help is apprecietad!

Reimund
  • 2,346
  • 1
  • 21
  • 25

2 Answers2

12

With the help from lazerscience and this post I ended up with the following.

The ModelAdmin:

class GalleryAdmin(admin.ModelAdmin):

    form = GalleryForm
    
    def __init__(self, model, admin_site):
        self.form.admin_site = admin_site 
        super(GalleryAdmin, self).__init__(model, admin_site)

And my form:

from django.contrib.admin.widgets import RelatedFieldWidgetWrapper


class GalleryForm(ModelForm):

    photos = ThumbnailChoiceField(queryset=Photo.objects.all(), label='Photos', widget=MyWidget(), required=False)

    def __init__(self, *args, **kwargs):
        super(GalleryForm, self).__init__(*args, **kwargs)
        rel = ManyToOneRel(self.instance.photos.model, 'id') 
        self.fields['photos'].widget = RelatedFieldWidgetWrapper(self.fields['photos'].widget, rel, self.admin_site) 
JGC
  • 5,725
  • 1
  • 32
  • 30
Reimund
  • 2,346
  • 1
  • 21
  • 25
  • In Django 1.2 an exception is raised saying that the form doesn't have a `admin_site` attribute. Am I doing something wrong? – orokusaki Jan 05 '11 at 21:50
  • @orokusaki A bit too late (like 7 years after) but you can try: `from django.contrib.admin import site as admin_site` as seen [here](https://github.com/django/django/blob/9dc83c356d363c090f3351c908cad6f823aeb7bf/tests/admin_inlines/tests.py#L9) – raratiru Nov 20 '17 at 12:59
  • Thanks, Reimund for the response, I have been struggling to come up with this and your answer has really helped me. But now my issue is that the popup is replacing the current URL and cannot open in a popup window. How can I go about it? – NINSIIMA WILBER Sep 06 '21 at 15:48
8

Yes you are right, you have to wrap your widget with django.contrib.admin.widgets.RelatedFieldWidgetWrapper, which turns out to be a bit complicated since it expects the current admin site as a parameter for initialization! Maybe you will find this post helpful!

Bernhard Vallant
  • 49,468
  • 20
  • 120
  • 148