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'}