[PYTHON] GraphQL-API mit graphene_django in Django

GraphQL-API mit graphene_django in Django

Dieser Artikel ist der 19. Tagesartikel von Django Adventskalender 2016.

Ein Python-Framework für GraphQL ist Graphen. Graphen verfügt über mehrere Bibliotheken, die mit O / R Mapper einfacher zu verwenden sind. Dieses Mal werde ich einen von ihnen [Graphen-Django] verwenden (https://github.com/graphql-python/graphene-django/).

Installation

Lassen Sie uns eine venv-Umgebung erstellen und aktivieren.

$ ~/ng/home/src/develop/pyvm/pythons/Python-3.5.2/bin/python3 -m venv env
$ source env/bin/activate
(env) $

Mit pip installieren.

(env) $ pip install graphene_django
Collecting graphene-django
  Using cached graphene-django-1.2.1.tar.gz
Collecting six>=1.10.0 (from graphene-django)
Collecting graphene>=1.1.3 (from graphene-django)
  Using cached graphene-1.1.3.tar.gz
Collecting Django>=1.6.0 (from graphene-django)
  Using cached Django-1.10.4-py2.py3-none-any.whl
Collecting iso8601 (from graphene-django)
  Using cached iso8601-0.1.11-py2.py3-none-any.whl
Collecting singledispatch>=3.4.0.3 (from graphene-django)
  Using cached singledispatch-3.4.0.3-py2.py3-none-any.whl
Collecting graphql-core>=1.0.1 (from graphene>=1.1.3->graphene-django)
  Using cached graphql-core-1.0.1.tar.gz
Collecting graphql-relay>=0.4.5 (from graphene>=1.1.3->graphene-django)
  Using cached graphql-relay-0.4.5.tar.gz
Collecting promise>=1.0.1 (from graphene>=1.1.3->graphene-django)
  Using cached promise-1.0.1.tar.gz
Collecting typing (from promise>=1.0.1->graphene>=1.1.3->graphene-django)
  Using cached typing-3.5.2.2.tar.gz
Installing collected packages: six, typing, promise, graphql-core, graphql-relay, graphene, Django, iso8601, singledispatch, graphene-django
  Running setup.py install for typing ... done
  Running setup.py install for promise ... done
  Running setup.py install for graphql-core ... done
  Running setup.py install for graphql-relay ... done
  Running setup.py install for graphene ... done
  Running setup.py install for graphene-django ... done
Successfully installed Django-1.10.4 graphene-1.1.3 graphene-django-1.2.1 graphql-core-1.0.1 graphql-relay-0.4.5 iso8601-0.1.11 promise-1.0.1 singledispatch-3.4.0.3 six-1.10.0 typing-3.5.2.2

Erstellen Sie ein Projekt

Erstellen Sie ein Projekt mit django-admin startprojet. Lassen Sie es vorerst als "myproj".

(env) $ django-admin startproject myproj .

Die Verzeichnisstruktur sieht so aus.

(env) $ tree myproj
myproj
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py

Schema definieren

Definieren wir das API-Schema in myproj / schema.py.

import graphene
from graphene_django import DjangoObjectType
from django.contrib.auth import models as auth_models


class User(DjangoObjectType):
    class Meta:
        model = auth_models.User


class Query(graphene.ObjectType):
    users = graphene.List(User)

    @graphene.resolve_only_args
    def resolve_users(self):
        return auth_models.User.objects.all()


schema = graphene.Schema(query=Query)

Ich habe "django.contrib.auth.models.User ()" verwendet, weil das Erstellen eines Modells mühsam war.

Einstellungen hinzufügen

Wir werden Einstellungen für graphene_django hinzufügen.

Fügen Sie graphene_django zu INSTALL_APPS hinzu

myproj/settings.py::

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'graphene_django',  # <-hinzufügen
]

Setzen Sie GRAPHENE auf den gepunkteten Namen des Schemas

Geben Sie in settings.py den gepunkteten Namen (wie foo.bar.baz) bis zu dem zuvor erstellten Schemaobjekt in schema.py an.

myproj/settings.py::

GRAPHENE = {
    'SCHEMA': 'myproj.schema.schema'
}

Fügen Sie eine URL hinzu, um graphql-Anforderungen zu akzeptieren

from django.conf.urls import url
from django.contrib import admin

from graphene_django.views import GraphQLView  # <-hinzufügen

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^graphql/', GraphQLView.as_view(graphiql=True)),  # <-hinzufügen
]

http: // localhost: 8000 / graphql / ist die URL, die API-Anforderungen akzeptiert. Es gibt einen Bildschirm namens graphiql zum Kompilieren von graphql-Anforderungen. Aktiviert durch Angabe von graphiql = True.

anfangen

Nach dem Migrieren starten wir es.

(env) $ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying sessions.0001_initial... OK
(env) $

Anlaufen.

(env) $ python manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).
December 20, 2016 - 13:28:32
Django version 1.10.4, using settings 'myproj.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Versuchen Sie, mit Ihrem Browser auf http: // localhost: 8000 / graphql / zuzugreifen.

Bildschirm wird angezeigt.

erhalten

Erstellen Sie einen Benutzer, da die Datenbank leer ist.

(env) $ python manage.py createsuperuser
Username (leave blank to use 'sximada'): foo
Email address: [email protected]
Password:
Password (again):
Superuser created successfully.

Lassen Sie uns eine Abfrage auf dem Grafikbildschirm ausgeben. Geben Sie im linken Bereich die folgende Abfrage ein.

query {
  users {
    id
    username
    email
    isSuperuser
        isStaff
  }
}

Klicken Sie nach der Eingabe auf die Wiedergabemarke oben links. Anschließend wird das folgende Ergebnis im rechten Bereich angezeigt.

{
  "data": {
    "users": [
      {
        "id": "1",
        "username": "foo",
        "email": "[email protected]",
        "isSuperuser": true,
        "isStaff": true
      }
    ]
  }
}

Ich konnte die Benutzerinformationen erhalten. Wenn es mehrere Benutzer gibt, ist dies wie folgt.

{
  "data": {
    "users": [
      {
        "id": "1",
        "username": "foo",
        "email": "[email protected]",
        "isSuperuser": true,
        "isStaff": true
      },
      {
        "id": "2",
        "username": "bar",
        "email": "[email protected]",
        "isSuperuser": true,
        "isStaff": true
      }
    ]
  }
}

Da proj.schema.Query.resolve_users () alle Benutzer zurückgibt Alle Benutzer werden als Liste ausgegeben.

    @graphene.resolve_only_args
    def resolve_users(self):
        return auth_models.User.objects.all()  # <-Hier

Holen Sie sich durch Angabe des Benutzers durch Angabe der ID

Ich möchte den Benutzer durch Angabe der ID angeben, also Ändern Sie die Query-Klasse in myproj / schema.py wie folgt:

myproj/schema.py::

class Query(graphene.ObjectType):
    user = graphene.Field(User, id=graphene.String())  # <-hinzufügen
    users = graphene.List(User)

    @graphene.resolve_only_args                                # <-hinzufügen
    def resolve_user(self, id):                                # <-hinzufügen
        return auth_models.User.objects.filter(pk=id).first()  # <-hinzufügen

    @graphene.resolve_only_args
    def resolve_users(self):
        return auth_models.User.objects.all()


Starten Sie den Entwicklungsserver neu und führen Sie die folgende Abfrage aus.

query {
  user(id: "1") {
    id
    username
    email
    isSuperuser
        isStaff
  }
}

Beim Ausführen erhalten Sie die folgenden Ergebnisse:

{
  "data": {
    "user": {
      "id": "1",
      "username": "foo",
      "email": "[email protected]",
      "isSuperuser": true,
      "isStaff": true
    }
  }
}

Diesmal konnte der durch id angegebene Benutzer abgerufen werden. Wenn Sie die E-Mail nicht benötigen, löschen Sie die E-Mail aus der Abfrage, und der API-Server gibt die E-Mail nicht zurück. Da Sie auf der Clientseite angeben können, welche Informationen Sie zurückgeben möchten (z. B. eine E-Mail). Die Analyse wird einfacher, und wenn Sie ein neues Feld erhalten möchten, indem Sie die Spezifikationen auf der Clientseite ändern Es scheint, dass die API-Seite nicht geändert werden muss. Außerdem müssen Sie keine unnötigen Daten austauschen.

Eine Sache, auf die Sie achten sollten, ist der Feldname mit einem Unterstrich. Der Unterstrich wird weggelassen und es wird ein unterer Kamelfall.

Beispiel)

Wenn die ID nicht vorhanden ist, ist .first () None, also null.

Abfrage ::

query {
  user(id: "6589645936543") {
    id
    username
    email
    isSuperuser
    isStaff
  }
}

Ergebnis::

{
  "data": {
    "user": null
  }
}

Sie können beide gleichzeitig anfordern

Abfrage ::

query {
  user(id: "1") {
    id
    username
    email
    isSuperuser
    isStaff
  }
  users {
    id
    username
    lastLogin
  }
}

Ergebnis::

{
  "data": {
    "user": {
      "id": "1",
      "username": "foo",
      "email": "[email protected]",
      "isSuperuser": true,
      "isStaff": true
    },
    "users": [
      {
        "id": "1",
        "username": "foo",
        "lastLogin": null
      },
      {
        "id": "2",
        "username": "bar",
        "lastLogin": null
      }
    ]
  }
}

Filter

In einer tatsächlichen Anwendung, anstatt alle Datensätze abzurufen Es ist wahrscheinlicher, dass Sie nach Bedingungen filtern.

Schreiben Sie die vorherigen Benutzer neu, damit sie gefiltert werden können.

import graphene
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField  # <-hinzufügen

from django.contrib.auth import models as auth_models


class User(DjangoObjectType):
    class Meta:
        model = auth_models.User
        filter_fields = ('username', 'email', 'is_staff')  # <-hinzufügen
        interfaces = (graphene.relay.Node,)                # <-hinzufügen


class Query(graphene.ObjectType):
    user = graphene.Field(User, id=graphene.String())
    users = DjangoFilterConnectionField(User)  # <-Veränderung

    @graphene.resolve_only_args
    def resolve_user(self, id):
        return auth_models.User.objects.filter(pk=id).first()

    # resolve_users()Methode löschen

schema = graphene.Schema(query=Query)

Geben Sie den Attributnamen des Modells in filter_fields an. Sie können nach den hier angegebenen Attributen filtern.

Starten Sie den Entwicklungsserver neu und führen Sie die folgende Abfrage aus.

query {
  users(isStaff: true) {
    edges {
      node {
        username
        email
        isStaff
      }
    }
  }
}

Es wird als "isStaff: true" angegeben. Es werden nur Benutzer mit dem Attribut staff zurückgegeben.

{
  "data": {
    "users": {
      "edges": [
        {
          "node": {
            "username": "foo",
            "email": "[email protected]",
            "isStaff": true
          }
        },
        {
          "node": {
            "username": "bar",
            "email": "[email protected]",
            "isStaff": true
          }
        }
      ]
    }
  }
}

Wenn Sie das Personalattribut des Benutzers "foo" entfernen, erhalten Sie das folgende Ergebnis.

{
  "data": {
    "users": {
      "edges": [
        {
          "node": {
            "username": "bar",
            "email": "[email protected]",
            "isStaff": true
          }
        }
      ]
    }
  }
}

Zuständigkeit

Es war ein Eindruck, dass ich es leicht berührte, aber ich fühlte, dass ich eine Gewohnheit hatte. Natürlich müssen Sie GraphQL kennen, um es in der Produktion verwenden zu können. Ich muss verstehen, wie man Graphen benutzt und wie man Graphen_django benutzt. Ich werde in eine Situation geraten, in der ich süchtig danach bin und nicht mehr raus kann.

Ich dachte jedoch auch, dass es je nach Verwendungszweck sehr praktisch wäre. Es ist gut, weil Sie nur eine Anfrage benötigen, um die API mehrmals aufzunehmen und anzuzeigen. GraphQL ist eine von Facebook veröffentlichte Spezifikation und kann in Relay am Frontend verwendet werden. Ich wollte auch damit spielen.

Recommended Posts

GraphQL-API mit graphene_django in Django
Erstellen Sie eine API mit Django
Qiita API Oauth mit Django
Laden Sie die Django-Shell mit ipython neu
Versuchen Sie, die Spotify-API in Django zu aktivieren.
Modell in Django
Internationalisierung mit Django
CRUD mit Django
Form in Django
Speichern Sie mehrere Modelle in einem Formular mit Django
Erstellen Sie mit Vagrant in 5 Minuten eine Django-Umgebung
So erstellen Sie eine Rest-API in Django
Implementierung der Authentifizierungsfunktion in Django REST Framework mit djoser
Django 1.11 wurde mit Python3.6 gestartet
Entwickeln Sie eine Web-API, die in DB gespeicherte Daten mit Django und SQLite zurückgibt
Entwicklungsverdauung mit Django
PDF mit Django ausgeben
Markdown-Ausgabe mit Django
Klicken Sie nach der Oauth-Authentifizierung mit Django auf die Twitter-API
Verwenden Sie Gentelella mit Django
Spielen mit der benutzerlokalen API für künstliche Intelligenz in Python
Twitter OAuth mit Django
Evernote-API in Python
Erste Schritte mit Django 1
Mail mit Django senden
Modelländerungen in Django
Extrudieren Sie mit der Fusion360-API
Erstellen Sie mit Django dynamisch Tabellen im Schema und generieren Sie dynamisch Modelle
Pooling mechanisieren mit Django
C-API in Python 3
Verwenden Sie MySQL mit Django
Django ab heute
Erste Schritte mit Django 2
Implementieren Sie hierarchische URLs mit drf-verschachtelten Routern im Django REST-Framework
Ablauf des Extrahierens von Text in PDF mit der Cloud Vision API
Versuchen Sie, Python in der mit pipenv erstellten Django-Umgebung auszuführen
[Django] Verwalten Sie Einstellungen wie das Schreiben in settings.py mit einem Modell
[Django] Wie man Eingabewerte im Voraus mit ModelForm angibt
Bis Django etwas mit einem Linienbot zurückgibt!
Erstellen Sie eine Authentifizierungsfunktion mit django-allauth und CustomUser in Django
Ich kann mich mit Django 3 nicht auf der Admin-Seite anmelden
[Übersetzter Artikel] Fast API ist eigentlich sehr kompatibel mit Django
Holen Sie sich YouTube Live-Chat-Felder in Echtzeit mit API
Erstellen Sie eine Web-API, die Bilder mit Django liefern kann
(Für Anfänger) Versuchen Sie, mit Django eine einfache Web-API zu erstellen
Bildanalyse mit Objekterkennungs-API zum Ausprobieren in 1 Stunde
Stellen Sie die umgekehrte Geokodierung auf Japanisch mit der Python Google Maps-API bereit
Erstellen Sie mit Django eine API für die soziale Integration von Smartphone-Apps
Hit Mastodons API in Python
Bild herunterladen mit Flickr API
Leistungsoptimierung in Django 3.xx.
Mach Django mit CodeStar (Python3.6.8, Django2.2.9)
PHP var_dump-like in Django-Vorlage
Behandeln Sie Konstanten in Django-Vorlagen
Implementieren Sie die Follow-Funktion in Django
Fangen Sie mit Django an! ~ Tutorial ⑤ ~
Minimale Konfigurations-Website-Umgebung mit Django
Betreiben Sie LibreOffice mit Python
Schaben mit Chromedriver in Python
Verwenden Sie die Twitter-API mit Python