简体   繁体   中英

How to get data from external API to Django Rest Framework

I am creating a DRF project (only API's), where logged in user can specify how many people's randomly generated credentials he wants to receive.

Here's my problem: I want to get these credentials from an external API ( https://randomuser.me/api ). This website generates random users data in quantity specified in the url's "results" parameter. Ex. https://randomuser.me/api/?results=40

My question is:

How can I even get this data? I know JavaScript fetch() method might be useful but I don't actually know how to connect it with Django Rest Framework, and then manipulate it. I want to show the data to the user after he sends the POST request (only specifying the number of users to be generated) and also save the results in the database, so he can access them later on (through GET request).

If you have any ideas or tips I would be very grateful.

Thank you

Here is how you can make an API call in a Django Rest Framework API View:

Since you want to store external API request in a database. This is a example of model to store the user result.

models.py

from django.conf import settings

class Credential(models.Models):
    """ A user can have many generated credentials """
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    value = models.CharField()

    # Here we override the save method to avoid that each user request create new credentials on top of the existing one
    
    def __str__(self):
        return f"{self.user.username} - {self.value}"

views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
# Assume that you have installed requests: pip install requests
import requests
import json

class GenerateCredential(APIVIew):
    """ This view make and external api call, save the result and return 
        the data generated as json object """
    # Only authenticated user can make request on this view
    permission_classes = (IsAuthenticated, )
    def get(self, request, format=None):
        # The url is like https://localhost:8000/api/?results=40
        results = self.request.query_params.get('type')
        response = {}
        # Make an external api request ( use auth if authentication is required for the external API)
        r = requests.get('https://randomuser.me/api/?results=40', auth=('user', 'pass'))
        r_status = r.status_code
        # If it is a success
        if r_status = 200:
            # convert the json result to python object
            data = json.loads(r.json)
            # Loop through the credentials and save them
            # But it is good to avoid that each user request create new 
            # credentials on top of the existing one
            # ( you can retrieve and delete the old one and save the news credentials )
            for c in data:
                credential = Credential(user = self.request.user, value=c)
                credential.save()
            response['status'] = 200
            response['message'] = 'success'
            response['credentials'] = data
        else:
            response['status'] = r.status_code
            response['message'] = 'error'
            response['credentials'] = {}
        return Response(response)


class UserCredentials(APIView):
    """This view return the current authenticated user credentials """
    
    permission_classes = (IsAuthenticated, )
    
    def get(self, request, format=None):
        current_user = self.request.user
        credentials = Credential.objects.filter(user__id=current_user)
        return Response(credentials)

NB: These views assume that the user who make the request is authenticated, more infos here . Because we need user to save the retrieved credentials in the database.

urls.py

path('api/get_user_credentials/', views.UserCredentials.as_view()),
path('api/generate_credentials/', views.GenerateCredentials.as_view()),

.js

const url = "http://localhost:8000/api/generate_credentials/";
# const url = "http://localhost:8000/api/get_user_credentials/";

fetch(url)
.then((resp) => resp.json())
.then(function(data) {
    console.log(data);
})
.catch(function(error) {
    console.log(error);
});
**how to call external api in Django view**
#convert img in base64string
    def encode(img):
            with open(img, "rb") as image_file:
                encoded_string = base64.b64encode(image_file.read())
            return encoded_string

#Django View Function
from django.conf import settings
def store_new_camera(request):

    Data = {}
    
    try:
        lChannel_no = request.POST.get('name')
        lCamera_name = request.POST.get('name')
        lCamera_id = request.POST.get('camera_id')
        lCompany_id = request.POST.get('company_id')
        lWearhouse = request.POST.get('wearhouse')
    
        media_dir = settings.MEDIA_ROOT
        image_dir = media_dir + "\\" + str('media') + "\\" + str('entrance_img') + "\\" + str(temp_file_name)
        data = encode(image_dir)
        picture = data
        try:
            url = "#BaseURL or endpoint"

            payload = '[{\"cameraId\":"' + str(lCamera_id) + '","companyId\":"' + str(lCompany_id) + '",\"name\": "' + str(
                lCamera_name) + '",\"warehouse\":"' + str(lWearhouse) + '",\"picture\": "' + str(
                picture) + '", \"channelNo\":"' + str(lChannel_no) + '"\r\n\t}]'

            headers = {
                'HodHodApiKey': 'xyz',
                'Content-Type': 'application/json'
            }

            response = requests.request("POST", url, headers=headers, data=payload)

            print(response.text)
        except Exception as e:
            import os, sys
            exception_type, exception_object, exception_traceback = sys.exc_info()
            filename = exception_traceback.tb_frame.f_code.co_filename
            line_number = exception_traceback.tb_lineno
            print("Exception type: ", exception_type)
            print("File name: ", filename)
            print("Line number: ", line_number)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM