1

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

enter image description here

but when i open it with a rss viewer it doesn't show those extra fields or the image

enter image description here

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

Shantanu Bedajna
  • 559
  • 10
  • 34

1 Answers1

8

<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:

Using enclosures

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:

First Solution (Image Stored in Django)

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]))]

 

Second Solution (Image not Stored in Django)

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)]

Image information in 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

castis
  • 8,154
  • 4
  • 41
  • 63
ruddra
  • 50,746
  • 7
  • 78
  • 101