7
votes

Passage de la session de la vue de modèle à Python Demandes API Call

Je souhaite effectuer plusieurs appels d'API de repos internes à partir de My Django Modyview, à l'aide de demandes de bibliothèque. Maintenant, je veux aussi transmettre la session de la vue du modèle à l'appel de l'API. Quelle est la façon recommandée de le faire, maintenir la performance à l'esprit.

En ce moment, j'extrise Cookie dans la demande actuelle objet dans la vue du modèle et en passant que pour demande.get () ou demande.post () appel. Mais problème avec c'est-à-dire, je devrais passer demande objet à mon client API, que je ne veux pas.

Ceci est l'emballage actuel que j'utilise pour acheminer mon Demandes: xxx

essentiellement, je veux me débarrasser de ce paramètre (1st param), car alors pour l'appeler, je dois continuer à passer Demande Objet dans Templateviews aux services internes. En outre, comment puis-je conserver la connexion persistante sur plusieurs appels?


8 commentaires

Quelques questions: Comment recevez-vous les données?, Qu'essayez-vous d'accomplir en général? Sont ces appels d'API sortants? Avez-vous besoin de passer l'objet de la session entière? On dirait qu'un cas d'utilisation inhabituelle, mais j'ai besoin de voir une image plus grande. Pouvez-vous s'il vous plaît expliquer ce qui tente d'accomplir. Merci.


@MarioDev: J'ai un templateview de Django. Je veux collecter des données pour mettre dans son contexte cette vue. Pour cela, je vais appeler une API de repos, c'est à nouveau dans mon application. Mais faire un appel d'API de repos sera un nouvel appel et donc si je ne passe pas cookie , alors session il y aurait différent de ce qu'il est dans templateview, que je n'ai pas 't veux. Fondamentalement, je veux conserver l'authentification valide pour les appels d'API internes.


@MarioDev: DATA est juste un dictionnaire Python.


Chaque fois que vous traitez avec des demandes d'API, il est toujours préférable de passer des jetons pour Auth (smth comme JWT devrait fonctionner dans ce cas). Bien que je sois toujours confus, pourquoi utilisez-vous des appels API? Pourquoi ne pas simplement utiliser la fonction interne ou la méthode de classe pointant sur le point final de réception? Comme vous le prétendez, vous n'utilisez-le que en interne, donc je ne vois aucun point d'avoir des appels d'API ..


Y a-t-il une raison pour laquelle vous ne pouvez pas simplement appeler la fonction API de repos de votre vue et simplement passer le long des données dans votre contexte de modèle? Django fonctionne sur un cycle de demande, vue, modèle, réponse. Vous essayez d'ajouter une étape ici et de la faire une demande, une vue, un modèle, une vue, une réponse, ce qui n'a jamais été conçu pour fonctionner.


@Titusp N'est-ce pas un scénario courant pour avoir une API de repos exposée pour notre application, qui est ensuite consommée sur le site Web (Templateview) ou l'application Android, ou toute autre plate-forme? Pourquoi Django aurait-il une restriction pour un cas d'utilisation aussi commun? Les API de repos sont le moyen de parler du système. Les fonctions d'appel pour obtenir le travail effectué, fonctionnent quelque temps, mais pas dans tous les scénarios.


Oui, c'est un scénario très courant. Toutefois, ces appels d'API ne sont pas fabriqués à partir du modèle, ils sont effectués après la charge de HTML et JavaScript dans le navigateur de l'utilisateur. Donc, vous rendantez le modèle, renvoyez-le comme la réponse à la demande, puis, après que l'utilisateur reçoit la réponse de la réponse, leur navigateur peut exécuter le JavaScript nécessaire pour effectuer l'appel de l'API de repos. L'API de repos est destinée à la consommation de données externe, non interne. Internal à votre propre application Django, vous devez simplement charger les données et le transmettre en tant que contexte de modèle.


En supposant que vous ayez réellement besoin de faire des appels d'API, je pense que cela se résume à un refactoring du code. J'ai posté une réponse.


3 Réponses :


1
votes

Si vous souhaitez éviter de passer la requête code> sur code> à wrap_internal_api_call code>, tout ce que vous avez à faire est de faire un peu plus de travail à la fin du modèle d'envoi où vous appelez l'API. wrapper. Notez que votre wrapper original fait beaucoup de cookies si des cookies d'autre request.cokies code>. Vous pouvez facturer cela sur le site d'appel. Réécrivez votre emballage API comme suit:

cookies_param = cookies or request.COOKIES
referer_param = request.META.get['HTTP_REFERER']
wrap_internal_api_call(referer_param, requests_api, uri, data, params, cookies_param, is_json, files)


0 commentaires

4
votes

REST VS invoquant la vue directement

Bien qu'il soit possible pour une application Web de faire un appel de repos à l'API. Ce n'est pas ce que le repos est conçu pour. Considérons les suivants de: https://docs.djangoproject.com/ja/ 1.9 / Rubriques / http / middleware /

Django Demander la réponse du cycle de vie

Comme vous pouvez le voir un cycle de demande / réponse Django a Pas mal de surcharge. Ajoutez à cela la surcharge du réservoir WebServer et WSGI. Au client côté client, vous avez la surcharge associée à la bibliothèque de demandes, mais accrochez-vous sur une seconde, le client se trouve également à la même application Web afin qu'il puisse également faire partie de la surcharge de l'application Web. Et il y a le problème de la péristence (ce que je vais venir à peu de temps).

Dernier mais non le moindre, si vous avez une configuration de DNS Round Robin, votre demande peut réellement sortir sur le fil avant de revenir au fil avant de revenir à la même serveur. Il y a une meilleure façon, d'invoquer la vue directement.

Pour appeler une autre vue sans l'appel de l'API de repos est vraiment facile xxx

Ceci a été discuté Quelques fois ici sur des liens tels que basé sur la classe d'appels Django Vue d'une autre vue basée sur la classe et Puis-je appeler Une vue d'une autre vue? donc je ne vais pas élaborer.

Demandes persistantes

Demandes HTTP persistantes (parle des demandes de python plutôt que django.http.request.httprequest ) sont gérés via des objets de session (à nouveau pas être confondu avec les sessions Django). Éviter la confusion est vraiment difficile:

L'objet de session vous permet de persister certains paramètres à travers Demandes. Il persiste également des cookies sur toutes les demandes fabriquées à partir du Instance de session, et utilisera la mise en commun de la connexion d'Urllib3. Donc si Vous faites plusieurs demandes au même hôte, le TCP sous-jacent la connexion sera réutilisée, ce qui peut entraîner une importante Augmentation des performances

Les différents hits à votre vue Django seront probablement issus de différents utilisateurs afin de ne pas vouloir réutiliser le même cookie pour l'appel de repos interne. L'autre problème est que l'objet de session Python ne peut pas être persisté entre deux coups différents à la vue Django. Les sockets ne peuvent généralement pas être sérialisées, une condition de les éliminer dans Memcached ou Redis.

Si vous voulez toujours persister avec le repos interne

Je pense que la réponse de @ Julian montre comment éviter Passer l'instance de demande Django en tant que paramètre.


4 commentaires

J'essayais donc l'approche d'appel de la vision directe et je me demandais comment passer des paramètres de requête sur les points de vue?


Vous passez l'objet de la demande entier. Donc, la deuxième vue peut l'attraper à partir de request.get


Cool. En fait, je voulais envoyer un paramètre de requête différent. J'ai donc modifié l'objet request.get . Mais le AS_View () renvoie un templateesponse semble-t-il. Comment puis-je sortir le Json? Avec API Call, je viens de faire réponse.json () pour obtenir. Maintenant, quand je fais réponse.Render (). Contenu , c'est une réponse du modèle.


Si la vue renvoie JSON, JSON_LOADS (Response.Rendered_Content)



-1
votes

Fondamentalement, je souhaite me débarrasser de ce paramètre de demande (1st param), car pour l'appeler, je dois conserver l'objet de la demande de passage à partir de modèles à des services internes. P>

Pour réussir la fonction arguments sans les transmettre explicitement dans des appels de fonction Vous pouvez utiliser des décorateurs pour envelopper vos fonctions et injecter automatiquement vos arguments. En utilisant cela avec une variable globale et du middleware Django pour l'enregistrement de la demande avant que votre vue résoudra votre problème. Voir ci-dessous pour une version résumée et simplifiée de ce que je veux dire. P>

demande_decorators.py h3> xxx pré>

extrait_request_middleware.py h3>

Voir les documents Django pour info sur la configuration du middleware P>

from internal_function import internal_function

def view_with_request(request):
    return internal_function() # here we don't need to pass in the request arg.

def run_test():

    request = "a request!"
    ExtractRequest().process_request(request)
    response = view_with_request(request)
    return response


if __name__ == '__main__':

    assert run_test() == "a request!"


1 commentaires

Soit, il est tout à fait difficile de savoir comment votre réponse répond à la question, ou votre réponse manque simplement le point. Pour moi, cela ressemble à un tour général pour passer un paramètre secrètement, c'est-à-dire sans qu'il soit visible. Là encore, cela ne semble même pas fonctionner dans votre exemple de code. Dans tous les cas, le paramètre "invisible" n'est pas ce que @ @hitjain a demandé.