Opened 4 weeks ago

Closed 3 weeks ago

#36151 closed Bug (wontfix)

Non-editable FieldError raised when using a GenericForeignKey on a form.

Reported by: James Pic Owned by: James Pic
Component: contrib.contenttypes Version: 5.1
Severity: Release blocker Keywords:
Cc: Adam Johnson, Mariusz Felisiak Triage Stage: Accepted
Has patch: yes Needs documentation: yes
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

https://code.djangoproject.com/ticket/35224 made GFK a Field with hard-coded editable=False

This breaks this very nice feature in Django 5.1 https://django-autocomplete-light.readthedocs.io/en/master/gfk.html

With exception: cannot be specified for TModel model form as it is a non-editable field. Check fields/fieldsets/exclude attributes of class TestAdmin

While I understand this is an interesting default protection for users, it would also be nice if Django would keep on allowing users to create their form fields for GFK if they want to, as they could until Django 5.0

Change History (10)

comment:1 by James Pic, 4 weeks ago

Component: Uncategorizedcontrib.contenttypes
Type: UncategorizedCleanup/optimization

comment:2 by James Pic, 4 weeks ago

Has patch: set

comment:3 by James Pic, 4 weeks ago

This fixes the problem enough https://github.com/django/django/pull/19110

If you want agree to any fix of this kind I'll gladly add a test.

TYIA for your feedback

comment:4 by James Pic, 4 weeks ago

In case any dal users stumbles on this, there's a documented monkey patch meanwhile this is fixed, or in case this won't be fixed https://github.com/yourlabs/django-autocomplete-light/commit/2e8933d2473409a19c624610800e077d3fbf1074

comment:5 by Sarah Boyce, 4 weeks ago

Cc: Adam Johnson Mariusz Felisiak added
Severity: NormalRelease blocker
Summary: editable GenericForeignKeyNon-editable FieldError raised when using a GenericForeignKey on a form.
Triage Stage: UnreviewedAccepted
Type: Cleanup/optimizationBug

This looks fiddly, but the following test fails on main, but was passing on 5.0 and is a regression in 6002df06713cb0a7050432263527a25754190c27

On main, the error is django.core.exceptions.FieldError: 'question' cannot be specified for Answer model form as it is a non-editable field.

  • tests/contenttypes_tests/test_fields.py

    a b  
    11import json
    22
     3from django import forms
    34from django.contrib.contenttypes.fields import GenericForeignKey
    45from django.contrib.contenttypes.prefetch import GenericPrefetch
    56from django.db import models
    class GenericForeignKeyTests(TestCase):  
    6566        answer.refresh_from_db()
    6667        self.assertIsNot(answer.question, old_question_obj)
    6768
     69    def test_form_field(self):
     70        class AnswerForm(forms.ModelForm):
     71            question = forms.CharField()
     72
     73            class Meta:
     74                model = Answer
     75                fields = ["question"]
     76
     77        form = AnswerForm()
     78        self.assertIn("question", form.fields)
     79
    6880
    6981class GenericRelationTests(TestCase):
    7082    def test_value_to_string(self):

However, note that question was excluded by default on the form.

Looks like this was also raised here: https://forum.djangoproject.com/t/non-editable-error-for-a-genericforeignkey-in-an-modelform-when-updating-to-version-5-1/35033

comment:6 by Sarah Boyce, 4 weeks ago

Needs documentation: set
Needs tests: set

comment:7 by Sarah Boyce, 4 weeks ago

Owner: set to James Pic
Status: newassigned

comment:8 by James Pic, 4 weeks ago

pushed test and docs, keeping the current behaviour and allowing to go back to the previous one with explicit editable=True
we can also restore the previous behaviour with editable=True by default, but I'm not convinced it was intended, given the hardcoding on editable=False in the said commit
although, perhaps the author just reproduced what he saw: a class attribute of editable=False https://github.com/django/django/commit/6002df06713cb0a7050432263527a25754190c27#diff-76b33afd71c30afb749a0de312cfe4a4578d78abae84a9d5db06388a4b1bc454L39
I'm willing to update the patch whenever a design decision is taken by authority though

comment:9 by Sarah Boyce, 3 weeks ago

Needs tests: unset
Patch needs improvement: set

comment:10 by Sarah Boyce, 3 weeks ago

Resolution: wontfix
Status: assignedclosed

Have considered and discussed this quite a bit

GenericForeignKey explicitly documents that they are not included on ModelForms. Part of the reason is that a GenericForeignKey would need a custom form field (with a custom widget), which is not currently defined on the GenericForeignKey.formfield() and would also be a little complicated (it doesn't make sense to have both this field and the underlying ct_field and fk_field defined on the field).

Hence, it makes sense for a custom EditableGenericForeignKey field to be defined in someone's project which uses the custom field widget in formfield and sets the field as editable=True (and likely sets the ct_field and fk_field as editable=False). This is roughly suggested as a solution in the forum discussion.

The behavior we now have is aligned to other fields and matches our documentation. Hence, I will update the status to wontfix.

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