Opened 10 years ago

Closed 10 years ago

#21615 closed Bug (wontfix)

contenttypes/generic.py regression from 1.6 --> 1.6.1

Reported by: kz26 Owned by: nobody
Component: contrib.contenttypes Version: 1.6
Severity: Release blocker Keywords: form modelform
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Model:

class Post(models.Model):
	class Meta:
		ordering = ['-modified']
	eid = models.CharField(max_length=40, blank=True, db_index=True)
	user = models.ForeignKey(settings.AUTH_USER_MODEL)
	school = models.ForeignKey(School)
	title = models.CharField(max_length=255, validators=[MinLengthValidator(5)])
	category = models.CharField(max_length=3, choices=ORIENTATION_CHOICES)
	affiliation = models.CharField(max_length=3, choices=AFFILIATION_CHOICES)
	age = models.CharField(max_length=255, help_text='Use a comma-separated list to enter more than one age, e.g. for couples and groups')
	external_replies = models.BooleanField(default=True)
	message = models.TextField()
	date = models.DateTimeField(default=timezone.now)
	modified = models.DateTimeField(null=True, blank=True)
	deleted = models.BooleanField(default=False)
	expiration = models.DateTimeField()
	replied = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, related_name="+")
	files = generic.GenericRelation(UploadedFile)

ModelForm:

class PostForm(forms.ModelForm):
	class Meta:
		model = Post
		fields = ('title', 'affiliation', 'category', 'age', 'external_replies', 'message', 'files')

	message = HTMLField(widget=CKEditorArea)
	files = forms.FileField(required=False, validators=[validate_filesize, validate_mm_filetype])

View:

class EditPost(UpdateView):
	model = Post
	form_class = PostForm
	template_name = "posts/new_edit_post.html"

	@transaction.atomic
	def form_valid(self, form):
		response = super(EditPost, self).form_valid(form)
		for f in self.request.FILES.getlist('files')[:settings.MAX_UPLOAD_COUNT - self.object.files.all().count()]:
			UploadedFile.objects.create(content_object=self.object, file=f)
		self.object.modified = timezone.now()
		self.object.save()
		return response

The edit view works fine in Django 1.6, but after upgrading to 1.6.1 I get the following stacktrace:

Traceback (most recent call last):

  File "/home/twosb/lib/python2.7/site-packages/django/core/handlers/base.py", line 114, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)

  File "/home/twosb/lib/python2.7/site-packages/django/views/generic/base.py", line 69, in view
    return self.dispatch(request, *args, **kwargs)

  File "/home/twosb/lib/python2.7/site-packages/django/utils/decorators.py", line 29, in _wrapper
    return bound_func(*args, **kwargs)

  File "/home/twosb/lib/python2.7/site-packages/django/contrib/auth/decorators.py", line 22, in _wrapped_view
    return view_func(request, *args, **kwargs)

  File "/home/twosb/lib/python2.7/site-packages/django/utils/decorators.py", line 25, in bound_func
    return func(self, *args2, **kwargs2)

  File "/home/twosb/app/twosb/posts/views.py", line 141, in dispatch
    response = super(EditPost, self).dispatch(request, *args, **kwargs)

  File "/home/twosb/lib/python2.7/site-packages/django/views/generic/base.py", line 87, in dispatch
    return handler(request, *args, **kwargs)

  File "/home/twosb/lib/python2.7/site-packages/django/views/generic/edit.py", line 228, in post
    return super(BaseUpdateView, self).post(request, *args, **kwargs)

  File "/home/twosb/lib/python2.7/site-packages/django/views/generic/edit.py", line 171, in post
    return self.form_valid(form)

  File "/home/twosb/lib/python2.7/site-packages/django/db/transaction.py", line 339, in inner
    return func(*args, **kwargs)

  File "/home/twosb/app/twosb/posts/views.py", line 148, in form_valid
    response = super(EditPost, self).form_valid(form)

  File "/home/twosb/lib/python2.7/site-packages/django/views/generic/edit.py", line 147, in form_valid
    self.object = form.save()

  File "/home/twosb/lib/python2.7/site-packages/django/forms/models.py", line 446, in save
    construct=False)

  File "/home/twosb/lib/python2.7/site-packages/django/forms/models.py", line 100, in save_instance
    save_m2m()

  File "/home/twosb/lib/python2.7/site-packages/django/forms/models.py", line 96, in save_m2m
    f.save_form_data(instance, cleaned_data[f.name])

  File "/home/twosb/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 516, in save_form_data
    setattr(instance, self.name, data)

  File "/home/twosb/lib/python2.7/site-packages/django/contrib/contenttypes/generic.py", line 292, in __set__
    for obj in value:

TypeError: 'NoneType' object is not iterable

Change History (3)

comment:1 by Tim Graham, 10 years ago

Severity: NormalRelease blocker
Triage Stage: UnreviewedAccepted

If you could construct a more minimal example to reproduce the problem (preferably in the form a test for Django's test suite) that will help us fix this.

comment:2 by Anssi Kääriäinen, 10 years ago

I am pretty sure I am responsible for the regression. So, I'll take a look.

comment:3 by Anssi Kääriäinen, 10 years ago

Resolution: wontfix
Status: newclosed

To me it seems this works exactly like it did in 1.5.

The idea here is that if the form has a field with the same name as GenericRelation's name in the model, then that form field will be used to supply data for the GenericRelation in saving. This didn't work in 1.6, and at least Mezzanine used heavily this feature. We can't have it both ways, and the fix for 1.6.1 was considered a regression fix. Or in other words, the way it worked in 1.6.0 wasn't considered correct.

A workaround is to rename the 'files', either in the form or the model. Doing this for the form is likely easier.

If there is in fact a change from the way this worked in 1.5 please reopen.

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