I am trying to use Django rss feeds to view feeds on rss viewer app.
i used from django.contrib.syndication.views import Feed
to create rss feeds
but it only had 3 fields title, description and link
i added custom fields by using from django.utils.feedgenerator import Rss201rev2Feed
and it generates the extra fields with no issues
but when i open it with a rss viewer it doesn't show those extra fields or the image
My question is how can i make those extra fields show up in app ?
does it not show up because app only shows title, description and link and those other fields are not processed ?
so how can i embed image and other fields in description so it shows up (most importantly image show up) ?
i have went over documentation many times can't seem to get it right.
here is the view code from Django app
class CustomFeedGenerator(Rss201rev2Feed):
def add_item_elements(self, handler, item):
super(CustomFeedGenerator, self).add_item_elements(handler, item)
handler.addQuickElement(u"image", item['image'])
handler.addQuickElement(u"seller_name", item['seller_name'])
handler.addQuickElement(u"price", item['price'])
class LatestPostsFeed(Feed):
title = "www.marktplaats.nl"
link = "/feeds/"
description = "Updates on changes and additions to posts published in the starter."
feed_type = CustomFeedGenerator
def items(self):
return Check_Ads_One.objects.order_by('title')[:5]
def item_title(self, item):
return item.title
def item_description(self, item):
return item.paragraph
def item_link(self, item):
return item.prod_link
def item_extra_kwargs(self, item):
return { 'image': item.image_link,
'seller_name' : item.seller_name,
'price': item.price,}
I'm using Rss Savvy for the reader app
<image></image>
is not a standard element of Items as per RSS Specification stated here
. But it is a valid element of channel
. Anyway, there are several ways you can add image to feed. Like:
As stated here
, you can use enclosures to add image in feed. Django Feed Framework also provides add_enclosures()
function which we can use. Here are two possible solutions based on that:
I am assuming you have an image field in the model like this:
class Check_Ads_One(models.Model):
image = models.ImageField()
Then update the LatestPostsFeed
class like this:
class LatestPostsFeed(Feed):
title = "www.marktplaats.nl"
link = "/feeds/"
description = "Updates on changes and additions to posts published in the starter."
feed_type = feedgenerator.Rss201rev2Feed
# Rest of the code
def get_object(self, request, *args, **kwargs):
self.request = request
return super(LatestPostsFeed, self).get_object(request, *args, **kwargs)
def get_image_url(self, url):
return self.request.build_absolute_uri('/media{}'.format(url))
def item_enclosures(self, item):
return [feedgenerator.Enclosure(self.get_image_url(item.image.url), str(item.image.size), 'image/{}'.format(item.image.name.split('.')[-1]))]
If you are storing the links of image instead of actual image, then use the following approach:
import urllib
class LatestPostsFeed(Feed):
title = "www.marktplaats.nl"
link = "/feeds/"
description = "Updates on changes and additions to posts published in the starter."
feed_type = feedgenerator.Rss201rev2Feed
# Rest of the code
def get_size_and_type_of_image(self, image_url):
# This method can be moved to models.py, and on save of `Check_Ads_One` it will calculate the size and type of image from url and store in DB. Then it will much optimized solution
data = urllib.urlopen(image_url)
return data['Content-Length'], data['Content-Type']
def item_enclosures(self, item):
content_length, content_type = self.get_size_and_type_of_image(item.image)
return [feedgenerator.Enclosure(item.image, content_length, content_type)]
CDATA
(alternative solution)You can add CDATA
tag in description and add image there:
def item_description(self, item):
return '<![CDATA[\n{} <img src="{}" alt="{}">\n]>'.format(item.paragraph, item.image, item.title)
More information can be found in this StackOverflow Answer