Tutorial :Model form is crashing on a foreign key in django



Question:

So I'm trying to create a new feed within the Admin page and its crashing with the error IntegrityError: lifestream_feed.lifestream_id may not be NULL, form['lifestream'] is set but form.instance.lifestream is not.

form.fields even shows that lifestream is a django.forms.models.ModelChoiceField

Here is the code:

class FeedCreationForm(forms.ModelForm):      class Meta:          model = Feed          exclude = ['name', 'domain', 'fetchable']        def parse_feed(self, feed_url):          feed = feedparser.parse(feed_url)            # Does the feed have errors          if feed['bozo']:              if feed['feed'].has_key("links"):                  for link in feed['feed']['links']:                      if link["type"] == "application/rss+xml":                          feed = self.parse_feed(link['href'])                          if not feed['bozo']:                              return feed          else:              return feed            return None        def clean(self):          """          Checks to make sure a feed url is valid and gets the feed  title          and domain.          """          feed_url = self.cleaned_data.get('url')          if not feed_url:              # Feed url was not validated by the field validator              return          feed = self.parse_feed(feed_url)          if feed:              feed_url = feed['url']              self.cleaned_data['url'] = feed_url          else:              # the feed was not parsed correctly.              import logging                self._errors['url'] = ErrorList(["This is not a valid  feed: %s" % feed['bozo_exception']])              logging.error(feed['bozo_exception'])              # This field is no longer valid. Remove from cleaned_data              del self.cleaned_data['url']              return            # Check if the feed has a title field          feed_info = feed.get('feed')          if not feed_info.get('title'):              self._errors['url'] = ErrorList(["This is not a valid  feed: The feed is empty"])              # This field is no longer valid. Remove from cleaned_data              del self.cleaned_data['url']              return          self.cleaned_data['name'] = feed_info['title']          self.instance.name = self.cleaned_data['name']          self.cleaned_data['domain'] = get_url_domain(feed_url)          self.instance.domain = self.cleaned_data['domain']            return self.cleaned_data    class FeedAdmin(admin.ModelAdmin):      list_display    = ('name', 'lifestream', 'domain', 'fetchable')      list_filter     = ('domain', 'lifestream')      actions         = ['make_fetchable', 'make_unfetchable']        add_form = FeedCreationForm      model = Feed        def make_unfetchable(self, request, queryset):          queryset.update(fetchable=False)      make_unfetchable.short_description = _(u"Mark as unfetchable")        def make_fetchable(self, request, queryset):          queryset.update(fetchable=True)      make_fetchable.short_description = _(u"Mark as fetchable")        def add_view(self, request):          if not self.has_change_permission(request):              raise PermissionDenied          if request.method == 'POST':              form = self.add_form(request.POST)              if form.is_valid():                  new_feed = form.save()                  msg = _('The %(name)s "%(obj)s" was added  successfully.') % {'name': 'user', 'obj': new_feed}                  self.log_addition(request, new_feed)                  if "_addanother" in request.POST:                      request.user.message_set.create(message=msg)                      return HttpResponseRedirect(request.path)                  elif '_popup' in request.REQUEST:                      return self.response_add(request, new_feed)                  else:                      request.user.message_set.create(message=msg + ' '  + ugettext("You may edit it again below."))                      # TODO: use reversed url                      return HttpResponseRedirect('../%s/' %  new_feed.id)          else:              form = self.add_form()            return render_to_response('admin/lifestream/feed/  add_form.html', {              'title': _('Add feed'),              'form': form,              'is_popup': '_popup' in request.REQUEST,              'add': True,              'change': False,              'has_add_permission': True,              'has_delete_permission': False,              'has_change_permission': True,              'has_file_field': False,              'has_absolute_url': False,              'auto_populated_fields': (),              'opts': self.model._meta,              'save_as': False,              #'username_help_text': self.model._meta.get_field  ('username').help_text,              'root_path': self.admin_site.root_path,              'app_label': self.model._meta.app_label,          }, context_instance=template.RequestContext(request))        def queryset(self, request):          return self.model.objects.feeds()    admin.site.register(Feed, FeedAdmin)    class Lifestream(models.Model):      """      A lifestream. Lifestreams can be created per user.      """      site = models.ForeignKey(Site, verbose_name=_(u"site"))      user = models.ForeignKey(User, verbose_name=_(u"user"))      slug = models.SlugField(_("slug"), help_text=_('Slug for use in  urls (Autopopulated from the title).'), blank=True)      title = models.CharField(_("title"), max_length=255)        def __unicode__(self):          return self.title    class FeedManager(models.Manager):      ''' Query only normal feeds. '''        def feeds(self):          return super(FeedManager, self).get_query_set()        def fetchable(self):          return self.feeds().filter(fetchable=True)    class Feed(models.Model):      '''A feed for gathering data.'''      lifestream = models.ForeignKey(Lifestream, verbose_name=_  ('lifestream'))      name = models.CharField(_("feed name"), max_length=255)      url = models.URLField(_("feed url"), help_text=_("Must be a valid  url."), verify_exists=True, max_length=1000)      domain = models.CharField(_("feed domain"), max_length=255)      fetchable = models.BooleanField(_("fetchable"), default=True)        # The feed plugin name used to process the incoming feed data.      plugin_class_name = models.CharField(_("plugin name"),  max_length=255, null=True, blank=True, choices=getattr(settings,  "PLUGINS", PLUGINS))        objects = FeedManager()        def __unicode__(self):          return self.name   

Its not returning the empty returns, its reaching the return self.cleaned_data:

-> return self.cleaned_data  (Pdb) list   85             self.cleaned_data['name'] = feed_info['title']   86             self.instance.name = self.cleaned_data['name']   87             self.cleaned_data['domain'] = get_url_domain(feed_url)   88             self.instance.domain = self.cleaned_data['domain']   89        90  ->         return self.cleaned_data   91        92     class FeedAdmin(admin.ModelAdmin):   93         list_display    = ('name', 'lifestream', 'domain', 'fetchable')   94         list_filter     = ('domain', 'lifestream')   95         actions         = ['make_fetchable', 'make_unfetchable']  (Pdb) self.cleaned_data  {'url': u'http://twitter.com/statuses/user_timeline/6166742.rss', 'domain': u'twitter.com', 'lifestream': <Lifestream: Social>, 'name': u'Twitter / sontek', 'plugin_class_name': u'lifestream.plugins.twitter.TwitterPlugin'}  


Solution:1

I believe the problem is in your clean() method.

The general clean() method (as opposed to field specific clean methods like clean_domain()) must return the cleaned_data dictionary (minus any fields which do not validate), and you have at least 3 returns in your clean method that do not return anything.

See here


Solution:2

Turns out this is a bug in HEAD of django


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »