Search code examples
pythondjangopython-3.xreddit

How can I use the Reddit API to render images in my HTML file


I am attempting to use the Python Reddit API Wrapper (Praw) to obtain the posts of a subreddit, and then display the image of the post in my HTML, using Django.

I am using Django 2.1.5, Python 3.6.3. I have been able to successfully obtain the URL for the images in a separate test python file, which simply prints out the URL to the console. Now I am trying to figure how I would be able to use django so that I can display the images in my HTML.

views.py

from django.shortcuts import render, praw, requests

def subRedditImage(request):
reddit = praw.Reddit(client_id='stuff', 
                    client_secret='stuff', 
                    user_agent='RedditScroller by XXX')
    subreddit = reddit.subreddit('FoodPorn')
    submissions = subreddit.hot(limit = 10)



    return render(request, 'scrollapp/base.html', submissions)

base.html

{% block content%}
<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, 
    shrink-to-fit=no">

    <title>Reddit</title>

    <h1>Hot posts</h1>
    <img src="{{ submissions }}" alt="">

  </body>
</html>
{% endblock content %}

I would like to display the images obtained from the reddit api on my html page.

I receive an error when attempting to load the page:

Traceback:

File "C:\Users\J\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\exception.py" in inner
  34.             response = get_response(request)

File "C:\Users\J\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\J\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\J\Desktop\redditscroll\scrollapp\views.py" in subRedditTitle
  30.     return render(request, 'scrollapp/base.html', submissions)

File "C:\Users\J\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\shortcuts.py" in render
  36.     content = loader.render_to_string(template_name, context, request, using=using)

File "C:\Users\J\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\template\loader.py" in render_to_string
  62.     return template.render(context, request)

File "C:\Users\J\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\template\backends\django.py" in render
  59.         context = make_context(context, request, autoescape=self.backend.engine.autoescape)

File "C:\Users\J\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\template\context.py" in make_context
  270.         raise TypeError('context must be a dict rather than %s.' % context.__class__.__name__)

Exception Type: TypeError at /
Exception Value: context must be a dict rather than ListingGenerator.



Solution

  • First of: Never publicly post your secret key. With that key I can do all sorts of things in your name. You should consider that like being your password. Don't commit it to a public repository, and don't post it to stackoverflow.

    The answer:

    The clue is in the error. You are providing the template with a ListingGenerator while it is expecting a dictionary. The object your submissions variable is referencing is a not a dict.

    You should get the data you want from the generator and add this to a dictionary before passing it to the template.

    The documentation for this is here.

    You could do something like this to get the url images:

        reddit = praw.Reddit(client_id='DONTPOSTTHIS',
                             client_secret='KEEPTHISASECRET',
                             user_agent='RedditScroller by XXX')
        subreddit = reddit.subreddit('FoodPorn')
    
        context = {}
        urls = []
    
        for submission in subreddit.hot(limit=10):
            urls.append(submission.url)
    
        context['urlList'] = urls
        print(context)
    

    You should pass that context to your template and use the data in whatever way you want. Start by replacing {{ submissions }} to {{ urlList.0 }} and after that, find out how you can loop through the list in the django template and show all 'hot' images in succession.