Opened 4 months ago

Closed 4 months ago

#35330 closed Bug (fixed)

The update of related objects fails in the admin when the related model is camel case.

Reported by: Devin Cox Owned by: Devin Cox
Component: contrib.admin Version: 5.0
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: yes

Description

Related to Ticket #34789

To reproduce, take these models:

class TransitionState(models.Model):
    label = models.CharField(max_length=255)

    def __str__(self):
        return self.label

class Transition(models.Model):
    source = models.ManyToManyField(TransitionState, related_name="transition_source")
    target = models.ForeignKey(
        TransitionState, on_delete=models.CASCADE, related_name="transition_target"
    )

and this admin:

class TransitionAdmin(admin.ModelAdmin):
    filter_horizontal = ["source"]

site.register(TransitionState)
site.register(Transition, TransitionAdmin)

When we add a "Target", we expect the "available" source to be populated with the new target. However, due to the camel casing of TransitionState, we cause data-model-ref to check transitionstate against transition state, and therefore does not pick up the match.

Proposed Change by @nessita as discussed in https://github.com/django/django/pull/17897:

diff --git a/django/contrib/admin/templates/admin/widgets/related_widget_wrapper.html b/django/contrib/admin/templates/admin/widgets/related_widget_wrapper.html
index 8e4356a95c..99b20545af 100644
--- a/django/contrib/admin/templates/admin/widgets/related_widget_wrapper.html
+++ b/django/contrib/admin/templates/admin/widgets/related_widget_wrapper.html
@@ -1,5 +1,5 @@
 {% load i18n static %}
-<div class="related-widget-wrapper" {% if not model_has_limit_choices_to %}data-model-ref="{{ model }}"{% endif %}>
+<div class="related-widget-wrapper" {% if not model_has_limit_choices_to %}data-model-ref="{{ model_name }}"{% endif %}>
     {{ rendered_widget }}
     {% block links %}
         {% spaceless %}
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
index fc0cd941d1..9633ebb1a1 100644
--- a/django/contrib/admin/widgets.py
+++ b/django/contrib/admin/widgets.py
@@ -328,6 +328,7 @@ class RelatedFieldWidgetWrapper(forms.Widget):
             "name": name,
             "url_params": url_params,
             "model": rel_opts.verbose_name,
+            "model_name": rel_opts.model_name,
             "can_add_related": self.can_add_related,
             "can_change_related": self.can_change_related,
             "can_delete_related": self.can_delete_related,

Change History (8)

comment:1 by Mariusz Felisiak, 4 months ago

Summary: The update of related objects fails in the admin when the related model has a name in camel case.The update of related objects fails in the admin when the related model is camel case.
Triage Stage: UnreviewedAccepted

Good catch.

comment:2 by Devin Cox, 4 months ago

If I want to use the test models from the PR listed in the ticket, should I just wait until that PR gets eventually merged in? Or is it preferred to make any changes here independent of another ticket (and subsequently make alterations to admin to work for this ticket)?

in reply to:  2 ; comment:3 by Devin Cox, 4 months ago

Replying to devin13cox:

If I want to use the test models from the PR listed in the ticket, should I just wait until that PR gets eventually merged in? Or is it preferred to make any changes here independent of another ticket (and subsequently make alterations to admin to work for this ticket)?

Or if there is another preferred way to approach this given the close relationship between this ticket, the one mentioned in the description, and #35331, I am open to suggestions!

in reply to:  3 ; comment:4 by Natalia Bidart, 4 months ago

Replying to devin13cox:

Replying to devin13cox:

If I want to use the test models from the PR listed in the ticket, should I just wait until that PR gets eventually merged in? Or is it preferred to make any changes here independent of another ticket (and subsequently make alterations to admin to work for this ticket)?

Or if there is another preferred way to approach this given the close relationship between this ticket, the one mentioned in the description, and #35331, I am open to suggestions!

Hi! My suggestion would be to progress with this ticket independently of the other tickets. Have you checked if any of the existing models would help building your testcase?

in reply to:  4 comment:5 by Devin Cox, 4 months ago

Replying to Natalia Bidart:

Replying to devin13cox:

Replying to devin13cox:

If I want to use the test models from the PR listed in the ticket, should I just wait until that PR gets eventually merged in? Or is it preferred to make any changes here independent of another ticket (and subsequently make alterations to admin to work for this ticket)?

Or if there is another preferred way to approach this given the close relationship between this ticket, the one mentioned in the description, and #35331, I am open to suggestions!

Hi! My suggestion would be to progress with this ticket independently of the other tickets. Have you checked if any of the existing models would help building your testcase?

I think the models Pizza and Topping are usable for Ticket #35331, but I would need to alter Topping to use camel casing for this one. Or add another filter horizontal admin, but at that point may be easier to make independent additions.

Edit: Might actually be reproducible without filter_horizontal if this is just a related update issue. I'll double check.

Last edited 4 months ago by Devin Cox (previous) (diff)

comment:7 by Natalia Bidart, 4 months ago

Triage Stage: AcceptedReady for checkin

comment:8 by GitHub <noreply@…>, 4 months ago

Resolution: fixed
Status: assignedclosed

In 8665cf03:

Fixed #35330 -- Fixed the update of related widgets when the referenced model is camel case named.

Co-authored-by: Natalia <124304+nessita@…>

Note: See TracTickets for help on using tickets.
Back to Top