Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add another popup #1140

Closed
tomgscs opened this issue Feb 27, 2020 · 4 comments
Closed

Add another popup #1140

tomgscs opened this issue Feb 27, 2020 · 4 comments

Comments

@tomgscs
Copy link

tomgscs commented Feb 27, 2020

The "add another" functionality of django admin (with related object popup) doesn't work with ModelSelect2. The + sign is not displayed on the field.

The functionality seems to appear in v2 documentation but not in v3 documentation.

@jpic
Copy link
Member

jpic commented Mar 18, 2020

Well it works for me :
2020-03-18-222129_538x48_scrot

The functionality seems to appear in v2 documentation but not in v3 documentation.

Because in dal v3 it relies purely on admin features (use django-add-another app outside the admin).

Did you try without dal on a normal select field ? Do you see the + sign then ?

@jpic
Copy link
Member

jpic commented Nov 26, 2021

Mystery solved. When using a ModelForm that declares a widget like this:

class TForm(forms.ModelForm):
    class Meta:
        model = TModel
        fields = ('name', 'test')
        widgets = {
            'test': autocomplete.ModelSelect2(url='select2_fk')
        }

Then the admin will generate its own ModelChoiceField and wrap its widget with the RelatedFieldWidgetWrapper.

When you register a ModelForm that declares a custom foreign key field as such:

    class PersonForm(forms.ModelForm):
        birth_country = forms.ModelChoiceField(
            queryset=Country.objects.all(),
            widget=autocomplete.ModelSelect2(url='country-autocomplete')
        )

        class Meta:
            model = Person
            fields = ('__all__')

Then Django will override it's foreign key field that has its widget decorated with RelatedFieldWidgetWrapper, with your declared one which does not have the decorator.

This is pretty annoying but understandable: if you specify your own field then Django does not know if it's compatible with its RelatedFieldWidgetWrapper.

Proof:

> /home/jpic/.local/lib/python3.9/site-packages/django/forms/models.py(279)__new__()
-> fields.update(new_class.declared_fields)
(Pdb) l
274  	                message = message % (', '.join(missing_fields),
275  	                                     opts.model.__name__)
276  	                raise FieldError(message)
277  	            # Override default model fields with any custom declared ones
278  	            # (plus, include all the other declared fields).
279  ->	            fields.update(new_class.declared_fields)
280  	        else:
281  	            fields = new_class.declared_fields
282
283  	        new_class.base_fields = fields
284
(Pdb) fields
{'name': <django.forms.fields.CharField object at 0x7f0a251cf0d0>, 'test': <django.forms.models.ModelChoiceField object at 0x7f0a251cf9a0>}
(Pdb) fields.declared_fields
*** AttributeError: 'dict' object has no attribute 'declared_fields'
(Pdb) new_class.declared_fields
{'test': <dal_alight.fields.ModelAlight object at 0x7f0a283b6460>}
(Pdb) new_class.declared_fields['test'].widget
<dal_alight.fields.ModelAlightWidget object at 0x7f0a283b6520>
(Pdb) fields['test'].widget
<django.contrib.admin.widgets.RelatedFieldWidgetWrapper object at 0x7f0a251cfdf0>

Here you can see that Django is about to override it's default field that has the RelatedFieldWidgetWrapper with my own declared field that does not have it.

@jpic jpic closed this as completed Nov 26, 2021
@jpic
Copy link
Member

jpic commented Nov 26, 2021

Solutions:

  • use Meta.widgets instead of declaring the field,
  • or, if you really want to declare the field: use djhacker to define your field instead of instanciating one in a form class declaration, because then django admin will wrap the widget inside RelatedWidgetWrapper
  • or, use django-add-another

@jpic
Copy link
Member

jpic commented Nov 26, 2021

Ticket created @ Django https://code.djangoproject.com/ticket/33321

Let's hope they'll agree to do something about it ... 😂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants