Django-filter: Les champs de filtre sont techniquement autorisés pour toutes les actions de vue DRF. Cela perturbe le schéma CoreAPI.

Créé le 16 mai 2018  ·  3Commentaires  ·  Source: carltongibson/django-filter

Lors de l'utilisation de CoreAPI avec DRF et DjangoFilterBackend activés, le client tente également de mapper tous les champs pour une action de création, de mise à jour ou de mise à jour partielle aux paramètres de requête. Cela interrompt la capacité du client à utiliser ces méthodes.

Exemple

Si nous avons une requête qui tente de créer un livre avec un nom, et que le nom est également un champ filtrable sur notre modèle :

# book views
class BookViewSet():
    filter_fields = ('name',)
   # ...
// schema
client.action('book', 'create', { 'name': 'My Awesome Book' });

Cela créera une requête avec à la fois le nom dans le paramètre d'URL ainsi que le corps de la requête. Ce n'est pas un comportement attendu.

POST /api/book?name=My%20Awesome%20Book

name=My Awesome Book

Solution proposée

Nous avons corrigé cela dans notre code en pointant à la place notre backend de filtre DRF vers un remplacement personnalisé avec le code suivant :

class OnlyFilterOnReadDjangoFilterBackend(DjangoFilterBackend):
    """ A filter backend that only allows for filtering by properties on
    actions deemed as safe. This means that create, update, and partial_update
    actions will not provide filter options.
    """
    SAFE_ACTIONS = ('list', 'retrieve')

    def get_schema_fields(self, view):
        if view.action in self.SAFE_ACTIONS:
            return super().get_schema_fields(view)
        return []

Commentaire le plus utile

Salut @Sonictherocketman. Merci pour le rapport.

Ma première pensée est qu'il s'agit d'un bogue avec l'API client - il ne fait pas la distinction entre les paramètres de chaîne de requête et le corps de la requête lors de la construction de la requête.

En général, désactiver simplement le filtrage pour les actions non sûres n'est pas correct. Le filtrage se produit lors de l'établissement de l'ensemble de requêtes de base sur lequel une mise à jour sera effectuée.

Je vais laisser ça ouvert pour l'instant, juste pour y réfléchir.

Tous les 3 commentaires

Salut @Sonictherocketman. Merci pour le rapport.

Ma première pensée est qu'il s'agit d'un bogue avec l'API client - il ne fait pas la distinction entre les paramètres de chaîne de requête et le corps de la requête lors de la construction de la requête.

En général, désactiver simplement le filtrage pour les actions non sûres n'est pas correct. Le filtrage se produit lors de l'établissement de l'ensemble de requêtes de base sur lequel une mise à jour sera effectuée.

Je vais laisser ça ouvert pour l'instant, juste pour y réfléchir.

Je pense aussi un peu que c'est un problème client, mais plus j'y pensais, j'ai l'impression que les actions n'ont pas vraiment de sens sur les requêtes d'écriture (en particulier l'écriture sur une ressource spécifique) et imo le schéma ne devrait pas avoir ces champs s'ils ne doivent pas être utilisés.

Merci pour la réponse rapide et je suis très intéressé par ce que vous en pensez.

Plus ou moins, je pense que nous sommes limités ici par nos désirs de génération de code _automagic_ dépassant la technologie (dans son état actuel).

Il y a beaucoup de choses que nous ne pouvons pas (encore) faire avec les schémas (dans l'un des formats disponibles) que nous aimerions - par exemple, avec CoreAPI, nous ne sommes pas encore en mesure de regrouper les paramètres pour qu'un filtre de plage de dates affiche qu'ils sont liés. (Il y a beaucoup plus que nous pouvons faire en écrivant des schémas à la main, mais personne ne veut le faire, bien sûr.)

Mais il évolue, et avec lui l'outillage. Ça va s'améliorer.

Que cette ligne particulière :

client.action('book', 'create', { 'name': 'My Awesome Book' });

utilise le même dict pour la chaîne de requête et le corps de la requête n'est pas génial. Je suppose que c'est l'abstraction qui fuit. Vous voulez vraiment créer cette requête _à la main_, en spécifiant les paramètres et le corps de la requête à des endroits distincts.

Ce n'est actuellement pas quelque chose que nous pouvons aborder ici. Merci encore pour le rapport cependant.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

nhuzaa picture nhuzaa  ·  3Commentaires

csarcom picture csarcom  ·  3Commentaires

jwineinger picture jwineinger  ·  3Commentaires

lalzada picture lalzada  ·  3Commentaires

chromakey picture chromakey  ·  5Commentaires