Jonas_Konig
Jonas_Konig

Reputation: 119

Django: Use JSON and requests in my django app

I am using JSON, re and requests to get the number of followers from an instagram page:

import json
import re
import requests

PROFILE = 'espn'

response = requests.get('https://www.instagram.com/' + PROFILE)
json_match = re.search(r'window\._sharedData = (.*);</script>', response.text)
profile_json = json.loads(json_match.group(1))['entry_data']['ProfilePage'][0]['graphql']['user']

print(profile_json['edge_followed_by']['count'])

I am wondering how I can then add this to my django project to use that number to display on my website, updating each time someone vists the page to reflect the dynamic number. I had a look around but I dont really understand where you would add this code. I would image it would be added in the views section to then be rendered in the html page but not sure what the format would be.

The view for the page I would like it to be used for example is View.py:

def index(request):
    post = Post.objects.all()[0]
    recent_posts = Post.objects.all()[1:4]
    latest_posts = Post.objects.all()[:5]

    data = {"post":post, "recent_posts":recent_posts, "latest_posts":latest_posts}
    return render(request, 'index.html', data)

Also as an extra question - how would the process differ if I was using a Generic Class-Based view vs a function view.

Thank you very much.

Upvotes: 0

Views: 103

Answers (2)

Yoni De Mulder
Yoni De Mulder

Reputation: 116

You can give the JSON profile_json as context of your function view and just access each element of the JSON in the Django Template.

import json
import re
import requests

def index(request):
    PROFILE = 'espn'
    response = requests.get('https://www.instagram.com/' + PROFILE)
    json_match = re.search(r'window\._sharedData = (.*);</script>', response.text)
    profile_json = json.loads(json_match.group(1))['entry_data']['ProfilePage'][0]['graphql']['user']
    context = {'profile': profile_json}
    return render(request, 'index.html', context)

Now, assuming that profile_json has a structure of {'followers': 2000}, you can access it in the Django template as follows: {{ profile.followers }} since the JSON was given under the name profile to the context of the view.

If you want to use Generic Class-Based Views, I suggest to use a TemplateView.

from django.views.generic import TemplateView


class ProfileTemplateView(TemplateView):
    template_name = 'index.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        PROFILE = 'espn'
        response = requests.get('https://www.instagram.com/' + PROFILE)
        json_match = re.search(r'window\._sharedData = (.*);</script>', response.text)
        profile_json = json.loads(json_match.group(1))['entry_data']['ProfilePage'][0]['graphql']['user']
        context['profile'] = profile_json
        return context

Next, you can access the profile context the same way as before in your Django template.

Upvotes: 1

Robin Zigmond
Robin Zigmond

Reputation: 18259

Just get the data as you are - but instead of printing the number, put it in a variable and include it in your template context:

def index(request):
    post = Post.objects.all()[0]
    recent_posts = Post.objects.all()[1:4]
    latest_posts = Post.objects.all()[:5]

    PROFILE = 'espn'

    response = requests.get('https://www.instagram.com/' + PROFILE)
    json_match = re.search(r'window\._sharedData = (.*);</script>', response.text)
    profile_json = json.loads(json_match.group(1))['entry_data']['ProfilePage'][0]['graphql']['user']

    page_visitors = profile_json['edge_followed_by']['count']

    data = {"post":post, "recent_posts":recent_posts, "latest_posts":latest posts, "page_visitors":page_visitors}
    return render(request, 'index.html', data)

In a class based view you would add this code to the get_context_data method.

Note though that this approach really isn't great - you appear to be scraping content from the Instagram webpage, which means you are heavily reliant on how that works, and your code could unexpectedly break at basically any time. I do not know if Instagram has an API that allows access to this information - but they likely do, and I would advise to make your requests to that instead.

Upvotes: 1

Related Questions