Note that there are some explanatory texts on larger screens.

plurals
  1. POUpgrading from Django 1.3 to 1.5.5 app unit test failing with AttributeError: PositionForm object has no attribute 'cleaned_data
    primarykey
    data
    text
    <p>I am upgrading from Django 1.3 to 1.5.5. All the tests worked before but now this one is failing and I cant figure out why. I have included the stack trace and functions that appear in the stack trace. There are a lot of log statements for debugging so be warned.</p> <pre><code>Traceback (most recent call last): File "/Users/athom09/Projects/openemory/openemoryEnv/lib/python2.7/site-packages/mock.py", line 1201, in patched return func(*args, **keywargs) File "/Users/athom09/Projects/openemory/openemory/../openemory/accounts/tests.py", line 878, in test_edit_profile response = self.client.post(edit_profile_url, self.profile_post_data) File "/Users/athom09/Projects/openemory/openemoryEnv/lib/python2.7/site-packages/django/test/client.py", line 463, in post response = super(Client, self).post(path, data=data, content_type=content_type, **extra) File "/Users/athom09/Projects/openemory/openemoryEnv/lib/python2.7/site-packages/django/test/client.py", line 297, in post return self.request(**r) File "/Users/athom09/Projects/openemory/openemoryEnv/lib/python2.7/site-packages/django/test/client.py", line 424, in request six.reraise(*exc_info) File "/Users/athom09/Projects/openemory/openemoryEnv/lib/python2.7/site-packages/django/core/handlers/base.py", line 115, in get_response response = callback(request, *callback_args, **callback_kwargs) File "/Users/athom09/Projects/openemory/openemory/../openemory/accounts/views.py", line 268, in public_profile form.save(commit=False) File "/Users/athom09/Projects/openemory/openemory/../openemory/accounts/forms.py", line 122, in save return super(ProfileForm, self).save(*args, **kwargs) File "/Users/athom09/Projects/openemory/openemory/../openemory/inlinemodelformsets.py", line 119, in save fset.save() File "/Users/athom09/Projects/openemory/openemoryEnv/lib/python2.7/site-packages/django/forms/models.py", line 514, in save return self.save_existing_objects(commit) + self.save_new_objects(commit) File "/Users/athom09/Projects/openemory/openemoryEnv/lib/python2.7/site-packages/django/forms/models.py", line 646, in save_new_objects if self.can_delete and self._should_delete_form(form): File "/Users/athom09/Projects/openemory/openemoryEnv/lib/python2.7/site-packages/django/forms/formsets.py", line 266, in _should_delete_form return form.cleaned_data.get(DELETION_FIELD_NAME, False) AttributeError: 'PositionForm' object has no attribute 'cleaned_data' </code></pre> <p>Accounts.test.py:</p> <pre><code>profile_post_data = { 'interests-MAX_NUM_FORMS': '', 'interests-INITIAL_FORMS': 0, 'interests-TOTAL_FORMS': 2, 'interests-0-interest': 'esoteric stuff', 'interests-0-DELETE': '', 'interests-1-interest': '', 'interests-1-DELETE': '', # degrees, with formset management fields '_DEGREES-MAX_NUM_FORMS': '', '_DEGREES-INITIAL_FORMS': 0, '_DEGREES-TOTAL_FORMS': 2, '_DEGREES-0-name': 'BA', '_DEGREES-0-institution': 'Somewhere Univ', '_DEGREES-0-year': 1876, '_DEGREES-1-name': 'MA', '_DEGREES-1-institution': 'Elsewhere Institute', # (degree year is optional) # positions, with same '_POSITIONS-MAX_NUM_FORMS': '', '_POSITIONS-INITIAL_FORMS': 0, '_POSITIONS-TOTAL_FORMS': 3, '_POSITIONS-0-name': 'Big Cheese, Association of Curd Curators', '_POSITIONS-1-name': 'Hole Editor, Journal of Swiss Studies', #external links '_EXTERNAL_LINKS-MAX_NUM_FORMS': '', '_EXTERNAL_LINKS-INITIAL_FORMS': 0, '_EXTERNAL_LINKS-TOTAL_FORMS': 2, '_EXTERNAL_LINKS-0-title': 'Google', '_EXTERNAL_LINKS-0-url': 'http://www.google.com', '_EXTERNAL_LINKS-1-title': 'Yahoo!', '_EXTERNAL_LINKS-1-url': 'http://www.yahoo.com', # grants: TODO: not currently included in templates # '_GRANTS-MAX_NUM_FORMS': '', # '_GRANTS-INITIAL_FORMS': 0, # '_GRANTS-TOTAL_FORMS': 3, # '_GRANTS-0-name': 'Advanced sharpness research', # '_GRANTS-0-grantor': 'Cheddar Institute', # '_GRANTS-0-project_title': 'The effect of subject cheesiness on cheddar sharpness assessment', # '_GRANTS-0-year': '1492', # '_GRANTS-1-grantor': u'Soci\xb4t\xb4 Brie', # '_GRANTS-1-project_title': 'A comprehensive analysis of yumminess', 'biography': 'Went to school *somewhere*, studied something else **elsewhere**.', } response = self.client.post(edit_profile_url, self.profile_post_data) </code></pre> <p>Accounts.views.py:</p> <pre><code>def public_profile(request, username): '''Display public profile information and publications for the requested author. When requested via AJAX, returns HTML that can be displayed inside a faculty dashboard tab. ''' user, userprofile = _get_profile_user(username) logger.info("AFTER USER") form, interest_formset = None, None context = {} if request.method == 'POST': logger.info("IN POST") form = ProfileForm(request.POST, request.FILES, instance=userprofile) logger.info("AFTER PROFILE FORM") interest_formset = InterestFormSet(request.POST, prefix='interests') logger.info("AFTER INTREST FORM") if form.is_valid() and interest_formset.is_valid(): logger.info("IN VALID FORM") logger.info("====================") logger.info(dir(form)) logger.info("--------------------") logger.info(dir(interest_formset)) logger.info("====================") # save and redirect to profile logger.info("B4 SAVE") form.save(commit=False) logger.info("AFTER SAVE") new_interests = [f.cleaned_data.get('interest') for f in interest_formset.forms if f.cleaned_data.get('interest', '') and not f.cleaned_data.get('DELETE', False)] logger.info("AFTER GET INTRESTS") userprofile.research_interests.set(*new_interests) logger.info("AFTER SET INTRESTS") # if a new photo file was posted, resize it if 'photo' in request.FILES: form.instance.resize_photo() userprofile.save() messages.success(request, 'Your profile was updated.') # TODO: might want a different behavior when POSTed via ajax logger.info("BEFORE POST REDIRECT") return HttpResponseSeeOtherRedirect(reverse('accounts:dashboard-profile', kwargs={'username': username})) else: logger.info("IN INVALID FORM") context['invalid_form'] = True if (request.user.has_perm("accounts.change_userprofile") or request.user == user) and not request.method == 'POST': form = ProfileForm(instance=userprofile) form.inlineformsets interest_data = [{'interest': i} for i in sorted(userprofile.research_interests.all())] interest_formset = InterestFormSet(initial=interest_data, prefix='interests') context.update({ 'author': user, 'form': form, 'interest_formset': interest_formset, }) if request.is_ajax(): # display a briefer version of the profile, for inclusion in faculty dash template_name = 'accounts/snippets/profile-tab.html' # for non-ajax requests, display full profile with documents else: # get articles where the user is the author articles_query = userprofile.recent_articles_query() paginated_articles, show_pages = paginate(request, articles_query) url_params = request.GET.copy() url_params.pop('page', None) context.update({ 'results': paginated_articles, 'show_pages': show_pages, 'url_params': url_params.urlencode(), }) template_name = 'accounts/profile.html' return render(request, template_name, context) </code></pre> <p>Accounts.forms.py:</p> <pre><code>def save(self, *args, **kwargs): logger.info("INSIDE SAVE") if hasattr(self, 'cleaned_data') and self.cleaned_data.get('delete_photo', False): logger.info("INSIDE CLEAN IF") # save=False because we're in the middle of save, and that would # probably cause this to go recursive or the world to implode or # something. logger.info("BEFORE PHOTO DELETE") self.instance.photo.delete(save=False) logger.info("AFTER PHOTO DELETE") logger.info("BEFORE SAVE RETURN") </code></pre> <p>inlinemodelformsets.py:</p> <pre><code>def save(self, *args, **kwargs): logger.info("IN PSAVE") instance = super(ModelForm, self).save(*args, **kwargs) if hasattr(self._forms, 'inlines'): for key, FormSet in self._forms.inlines.items(): fset = FormSet(self.data, self.files, prefix=self._get_formset_prefix(key), instance=instance) logger.info("BEFORE PSAVE FSET SAVE") fset.save() logger.info("BEFORE PSAVE RETURN") return instance return super(ProfileForm, self).save(*args, **kwargs) </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload