FAQ
#18357: BaseGenericInlineFormSet in Django Admin does not set generic foreign key
fields when constructing form
--------------------------------------+--------------------
Reporter: buettgenbach@… | Owner: nobody
Type: Bug | Status: new
Component: contrib.contenttypes | Version: 1.3
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------------+--------------------
For a BaseInlineFormSet in _construct_form the fk value is set in order to
do validation.

{{{
def _construct_form(self, i, **kwargs):
...
# Set the fk value here so that the form can do it's validation.
setattr(form.instance, self.fk.get_attname(), self.instance.pk)
return form
}}}

Something similar is missing for BaseGenericInlineFormSet. Actually it has
been removed in
[https://github.com/django/django/commit/856a39e841080abc34e8ae3bb2b20f780c33762d#L0R329].
As a consequence during model based cleaning the generic foreign key
attribute cannot be accessed/cleaned because it is not set. Assume the
following fictional code:

{{{
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')

class GenericChoice(models.Model):
content_type = models.ForeignKey(ContentType)
content_id = models.PositiveIntegerField()
content = generic.GenericForeignKey('content_type', 'content_id')
choice = models.CharField(max_length=200)
votes = models.IntegerField()

def clean(self):
if self.votes > 10 and self.content.question == 'Don't allow more
than 10 votes':
raise ValidationError('Test')
}}}

This results in an NoneType error since self.content is None.
With something like this in BaseGenericInlineFormSet it could be fixed:

{{{
def _construct_form(self, i, **kwargs):
# Avoid a circular import.
from django.contrib.contenttypes.models import ContentType
form = super(BaseGenericInlineFormSet, self)._construct_form(i,
**kwargs)
# if self.save_as_new:
# # Remove the key from the form's data, we are only creating
new instances.
# form.data[form.add_prefix(self.ct_fk_field.name)] = None
# form.data[form.add_prefix(self.ct_field.name)] = None

# Set the GenericForeignKey value here so that the form can do its
validation.
setattr(form.instance, self.ct_fk_field.attname, self.instance.pk)
setattr(form.instance, self.ct_field.attname,
ContentType.objects.get_for_model(self.instance).pk)
return form
}}}

But this would only fix those cases where the parent model already exists
(Admin edit). If the parent does not exist (for example when creating a
new Poll with some GenricChoice inline sets) the generic foreign key field
cannot be accessed since content_id is not set (and the _cache_content is
not set, too). Using a simple BaseInlineFormSet this is achieved by
setting the foreing key object through the InlineForeignKeyField which is
instantiated with the foreign key object during add_fields in
BaseInlineFormSet.

--
Ticket URL: <https://code.djangoproject.com/ticket/18357>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

--
You received this message because you are subscribed to the Google Groups "Django updates" group.
To post to this group, send email to django-updates@googlegroups.com.
To unsubscribe from this group, send email to django-updates+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-updates?hl=en.

Search Discussions

  • Django at Oct 25, 2012 at 10:59 pm
    #18357: BaseGenericInlineFormSet in Django Admin does not set generic foreign key
    fields when constructing form
    --------------------------------------+------------------------------------
    Reporter: buettgenbach@… | Owner: nobody
    Type: Bug | Status: new
    Component: contrib.contenttypes | Version: 1.3
    Severity: Normal | Resolution:
    Keywords: | Triage Stage: Accepted
    Has patch: 0 | Needs documentation: 0
    Needs tests: 0 | Patch needs improvement: 0
    Easy pickings: 0 | UI/UX: 0
    --------------------------------------+------------------------------------
    Changes (by lrekucki):

    * needs_better_patch: => 0
    * needs_docs: => 0
    * needs_tests: => 0
    * stage: Unreviewed => Accepted


    --
    Ticket URL: <https://code.djangoproject.com/ticket/18357#comment:1>
    Django <https://code.djangoproject.com/>
    The Web framework for perfectionists with deadlines.

    --
    You received this message because you are subscribed to the Google Groups "Django updates" group.
    To post to this group, send email to django-updates@googlegroups.com.
    To unsubscribe from this group, send email to django-updates+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupdjango-updates @
categoriesdjango, python
postedMay 21, '12 at 1:12p
activeOct 25, '12 at 10:59p
posts2
users1
websitedjangoproject.com

1 user in discussion

Django: 2 posts

People

Translate

site design / logo © 2018 Grokbase