web-dev-qa-db-fra.com

Moyen approprié de consommer les données de l’API RESTFUL dans django

J'essaie d'apprendre Django), bien que ma solution actuelle soit conforme aux meilleures pratiques de Django, j'aimerais afficher les informations d'une API Web sur mon site Web. Disons que l'URL de l'API est la suivante:

http://api.example.com/books?author=edwards&year=2009

Cette liste renverrait une liste de livres d’Edwards rédigés en 2009.

{'results':
             [
                {
                   'title':'Book 1',
                   'Author':'Edwards Man',
                   'Year':2009
                },
                {
                   'title':'Book 2',
                   'Author':'Edwards Man',
                   'Year':2009}
           ]
}

Actuellement, je consomme l'API dans mon fichier de vues comme suit:

class BooksPage(generic.TemplateView):
    def get(self,request):
        r = requests.get('http://api.example.com/books?author=edwards&year=2009')
        books = r.json()
        books_list = {'books':books['results']}
        return render(request,'books.html',books_list)

Normalement, nous récupérons les données de la base de données dans le fichier models.py, mais je ne suis pas sûr de pouvoir saisir ces données d'API dans models.py ou views.py. Si cela se trouve dans models.py, quelqu'un peut-il donner un exemple de la façon de procéder? J'ai écrit l'exemple ci-dessus de manière spécifique pour stackoverflow, de sorte que tous les bogues sont purement le résultat de l'écrire ici.

47
user2694306

J'aime l'approche consistant à placer ce type de logique dans une couche de service distincte (services.py); les données que vous rendez ne sont pas vraiment un "modèle" dans la logique Django, sens ORM, et c'est plus qu'une simple "vue". Une encapsulation propre vous permet de faire des choses comme contrôler l'interface le service de support (c'est-à-dire, faites-le ressembler à un Python avec des paramètres)), ajoutez des améliorations telles que la mise en cache, comme indiqué par @sobolevn, testez l'API de manière isolée, etc.

Donc, je suggère un simple services.py, ça ressemble à ça:

def get_books(year, author):
    url = 'http://api.example.com/books' 
    params = {'year': year, 'author': author}
    r = requests.get(url, params=params)
    books = r.json()
    books_list = {'books':books['results']}
    return books_list

Notez comment les paramètres sont passés (en utilisant une fonctionnalité du paquetage requests).

Puis dans views.py:

import services
class BooksPage(generic.TemplateView):
    def get(self,request):
        books_list = services.get_books('2009', 'edwards')
        return render(request,'books.html',books_list)

Voir également:

102
bimsapi

Utilisez le sérialiseur au lieu de .json, car il offre la possibilité de retourner dans un certain nombre de formats. Comme lors de l'utilisation de rest-api, l'utilisation du sérialiseur fourni est préférable.

Conservez également le traitement des données et obtenez les demandes de données dans view.py.Les formulaires sont utilisés pour la création de modèles et non comme logique métier.

3
Prateek099

Eh bien, il y a plusieurs choses à garder à l'esprit. Tout d’abord, dans ce cas, vos données ne changent pas si souvent. C'est donc une bonne pratique de mettre en cache ce type de réponses. Il existe de nombreux outils de mise en cache, mais redis est une option populaire. Vous pouvez également choisir une base de données NoSQL supplémentaire uniquement pour la mise en cache.

Deuxièmement, quel est le but d'afficher ces données? Vous attendez-vous à ce que vos utilisateurs interagissent avec des livres ou des auteurs, etc.? S'il s'agit simplement d'une information, les formulaires et les modèles ne sont pas nécessaires. Sinon, vous devez fournir des vues, des formulaires et des modèles appropriés pour les livres et les auteurs, etc.

Et compte tenu de l'endroit où vous devriez appeler une demande d'API, je dirais que cela dépend fortement de la deuxième question. Les choix sont:

  • views.py pour simplement afficher des données.
  • forms.py ou encore views.py pour inactivité.
1
sobolevn