(J'ai créé une balise appelée onefile parce que je veux parfois essayer les fonctions du framework gênantes avec un seul fichier. Vous pouvez le faire sans permission. Je ne sais pas si c'est le cas.)
django rest framework est un framework construit sur django. C'est pratique lors de la création d'une API REST. Il est difficile de vérifier les fonctions fournies. Après tout, lire le code source interne pour comprendre le comportement est souvent plus facile que lire la documentation. Il n'y a aucune perte, même si vous créez un environnement dans lequel vous pouvez facilement essayer les fonctions.
Vous pouvez essayer les fonctionnalités de django restframework avec le code suivant. (Vous pouvez le sauter sans le lire attentivement)
#L'histoire de la création de ce module de raccourcis
from shortcut import App # shorthand
from shortcut import do_get, do_post, do_delete
app = App()
app.setup(apps=[__name__], root_urlconf=__name__)
from rest_framework import routers, serializers, viewsets
# models
from django.contrib.auth.models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'url', 'username', 'email', 'is_staff')
# viewsets
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
# Routers provide an easy way of automatically determining the URL conf.
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
urlpatterns = app.setup_urlconf(router)
if __name__ == "__main__":
app.create_table(User)
parser = app.create_arg_parser()
args = parser.parse_args()
if args.run_server:
app.run_server(port=8080)
else:
app.run_client(main_client)
Précautions et explications sur l'utilisation.
Comme il dépend de shortcut.py
à créer ultérieurement, il doit avoir la structure suivante. (Bien sûr, vous pouvez faire le paquet sérieusement)
.
├── shortcut.py
└── view-sample1.py #Fichier que vous souhaitez essayer
L'ajout de view-sample1.py
et -
est inapproprié comme nom de module Python. (Personnellement, je donne un nom de fichier inapproprié car je veux une erreur d'importation lorsque je tente d'importer à partir d'autres personnes, mais cela n'a pas beaucoup de sens)
Il faut faire attention à l'ordre d'importation en raison de la mauvaise conception de django. L'ordre et la position des codes suivants doivent être respectés.
from shortcut import App # shorthand
from shortcut import do_get, do_post, do_delete
#Différents paramètres sont nécessaires avant d'importer le framework reste
app = App()
app.setup(apps=[__name__], root_urlconf=__name__)
#Importer des modules de modèle et de restframework
from django.contrib.auth.models import User
from rest_framework import routers, serializers, viewsets
Au moment où vous importez le module du framework django rest, vous pouvez obtenir une erreur telle que la nécessité de définir django, vous devez donc effectuer divers paramètres avant cela. Si vous voulez séparer ʻurls.pyou
django app, l'argument de ʻapp.setup ()
change. Cet article explique comment essayer avec un seul fichier, vous pouvez donc le réparer avec __name__
.
C'est une fonction du framework rest de django, donc je ne vais pas l'expliquer en détail. Voir la documentation etc.
from django.contrib.auth.models import User
# models
from rest_framework import routers, serializers, viewsets
# serializers
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'url', 'username', 'email', 'is_staff')
# viewsets
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
# Routers provide an easy way of automatically determining the URL conf.
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
urlpatterns = app.setup_urlconf(router)
Fondamentalement, serialier fournit la représentation et la variation de sortie du modèle, l'ensemble de vues est en charge d'une série de vues à l'aide du serialiezer, et si vous enregistrez l'ensemble de vues dans le routeur, vous pouvez utiliser diverses API REST.
Au fait, j'ai oublié. Lorsque vous essayez avec un fichier, il est nécessaire de définir __meta __. App_label
pour déterminer l'application django
à laquelle appartient le modèle à définir. Par exemple, il peut être défini comme suit.
class Skill(models.Model):
name = models.CharField(max_length=255, default="", null=False)
user = models.ForeignKey(User, null=False, related_name="skills")
class Meta:
app_label = __name__
Si vous le démarrez avec l'option --run-server
, il fonctionnera en fait comme une application. Comme l'API navigable est également activée, vous pouvez y accéder avec un navigateur, entrer une valeur dans le formulaire et essayer GET / POST / PUT / DELETE. En interne, il appelle simplement runserver
de django
.
$ python view-sample1.py --run-server
Performing system checks...
System check identified no issues (0 silenced).
You have unapplied migrations; your app may not work properly until they are applied.
Run 'python manage.py migrate' to apply them.
July 18, 2016 - 23:32:11
Django version 1.9.6, using settings None
Starting development server at http://127.0.0.1:8080/
Quit the server with CONTROL-C.
Puisque le modèle lui-même à utiliser est défini pour être enregistré dans la base de données en mémoire de sqlite, il est nécessaire de générer une table à chaque fois. Cela se fait ci-dessous.
app.create_table(User)
Lorsqu'il est exécuté sans argument, l'exemple d'exécution est affiché par django.test.client.Client
. Dans l'exemple ci-dessus, on suppose que main_client ()
est appelé, mais il n'est pas écrit. Par exemple, écrivez comme suit.
def main_client(client):
"""call view via Client"""
# success request
msg = "listing (empty)"
do_get(client, msg, "/users/")
msg = "create user (name=foo)"
do_post(client, msg, "/users/", {"username": "foo"})
msg = "create user (name=bar)"
do_post(client, msg, "/users/", {"username": "bar"})
msg = "listing"
do_get(client, msg, "/users/")
msg = "show information for user(id=1)"
do_get(client, msg, "/users/1/")
msg = "delete user(id=1)"
do_delete(client, msg, "/users/1")
msg = "listing"
do_get(client, msg, "/users/")
Le résultat de l'exécution est le suivant. (python view-sample1.py
)
listing (empty)
request: GET /users/
status code: 200
response: []
create user (name=foo)
request: POST /users/
status code: 201
response: {
"id": 1,
"url": "http://testserver/users/1/",
"username": "foo",
"email": "",
"is_staff": false
}
create user (name=bar)
request: POST /users/
status code: 201
response: {
"id": 2,
"url": "http://testserver/users/2/",
"username": "bar",
"email": "",
"is_staff": false
}
listing
request: GET /users/
status code: 200
response: [
{
"id": 1,
"url": "http://testserver/users/1/",
"username": "foo",
"email": "",
"is_staff": false
},
{
"id": 2,
"url": "http://testserver/users/2/",
"username": "bar",
"email": "",
"is_staff": false
}
]
show information for user(id=1)
request: GET /users/1/
status code: 200
response: {
"id": 1,
"url": "http://testserver/users/1/",
"username": "foo",
"email": "",
"is_staff": false
}
delete user(id=1)
request: DELETE /users/1/
status code: 204
listing
request: GET /users/
status code: 200
response: [
{
"id": 2,
"url": "http://testserver/users/2/",
"username": "bar",
"email": "",
"is_staff": false
}
]
shortcut.py
shortcut.py ressemble à ceci: Cette explication est gênante, donc je ne le ferai pas.
import os.path
import json
import copy
import importlib
import argparse
from django.db import connections
from django.test.client import Client
default_settings = dict(
DEBUG=True,
ALLOWED_HOSTS=['*'],
INSTALLED_APPS=[
"django.contrib.staticfiles",
"django.contrib.contenttypes",
"django.contrib.auth",
"rest_framework",
],
STATIC_URL='/static/',
MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
),
REST_FRAMEWORK={
"DEFAULT_PERMISSION_CLASS": [
"rest_framework.permissions.AllowAny"
]
},
DATABASES={"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": ":memory:"
}},
CACHES={
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
}
},
TEMPLATES=[
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True
},
]
)
def create_table(model, dbalias="default"):
connection = connections[dbalias]
with connection.schema_editor() as schema_editor:
schema_editor.create_model(model)
def maybe_list(x):
if isinstance(x, (list, tuple)):
return x
else:
return [x]
class SettingsHandler(object):
defaults = {
"settings": default_settings,
"STATIC_ROOT": None,
"dbalias": "default"
}
def get_settings_options(self, root_urlconf):
options = copy.copy(self.defaults["settings"])
options.update(
STATIC_ROOT=self.defaults["STATIC_ROOT"] or self.get_static_root(),
ROOT_URLCONF=root_urlconf
)
return options
def get_static_root(self):
import rest_framework
return os.path.abspath(os.path.join(rest_framework.__path__[0], 'static'))
class App(object):
def __init__(self, settings_handler=SettingsHandler()):
self.settings_handler = settings_handler
def setup(self, apps, root_urlconf, extra_settings=None):
import django
from django.conf import settings
apps = maybe_list(apps)
options = self.settings_handler.get_settings_options(root_urlconf)
options["INSTALLED_APPS"].extend(apps)
if extra_settings:
options.update(extra_settings)
settings.configure(**options)
django.setup()
def setup_urlconf(self, router):
# url
from django.conf.urls import url, include
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = [
url(r'^', include(router.urls))
]
urlpatterns += staticfiles_urlpatterns()
return urlpatterns
def load_module(self, module_name):
return importlib.import_module(module_name)
def run(self, main_client):
parser = self.create_arg_parser()
args = parser.parse_args()
if args.run_server:
self.run_server(port=8080)
else:
self.run_client(main_client)
def run_server(self, port=8000):
from django.core.management.commands.runserver import Command
return Command().execute(addrport=str(port))
def run_client(self, callback):
client = Client()
return callback(client)
def create_arg_parser(self):
parser = argparse.ArgumentParser()
parser.add_argument("--run-server", dest="run_server", action="store_true", default=False)
return parser
def create_table(self, *models):
for model in models:
create_table(model, dbalias=self.settings_handler.defaults["dbalias"])
def do_get(client, msg, path):
print(msg)
print("```")
print("request: GET {}".format(path))
response = client.get(path)
print("status code: {response.status_code}".format(response=response))
print("response: {content}".format(content=json.dumps(response.data, indent=2)))
print("```")
def do_post(client, msg, path, data):
print(msg)
print("```")
print("request: POST {}".format(path))
response = client.post(path, data)
print("status code: {response.status_code}".format(response=response))
print("response: {content}".format(content=json.dumps(response.data, indent=2)))
print("```")
def do_delete(client, msg, path):
print(msg)
print("```")
print("request: DELETE {}".format(path))
response = client.delete(path)
print("status code: {response.status_code}".format(response=response))
print("```")
Par exemple, vous pouvez essayer la fonction de pagination en apportant les modifications suivantes.
--- view-sample1.py 2016-07-18 23:39:33.000000000 +0900
+++ view-sample2.py 2016-07-19 00:02:14.000000000 +0900
@@ -16,10 +20,21 @@
fields = ('id', 'url', 'username', 'email', 'is_staff')
+# pagination
+from rest_framework import pagination
+
+
+class MyPagination(pagination.PageNumberPagination):
+ page_size = 5
+ page_size_query_param = 'page_size'
+ max_page_size = 10000
+
+
# viewsets
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
+ pagination_class = MyPagination
# Routers provide an easy way of automatically determining the URL conf.
Affichage de la liste avec page_size = 5.
request: GET /users/
status code: 200
response: {
"count": 10,
"next": "http://testserver/users/?page=2",
"previous": null,
"results": [
{
"id": 1,
"url": "http://testserver/users/1/",
"username": "foo0",
"email": "",
"is_staff": false
},
{
"id": 2,
"url": "http://testserver/users/2/",
"username": "foo1",
"email": "",
"is_staff": false
},
{
"id": 3,
"url": "http://testserver/users/3/",
"username": "foo2",
"email": "",
"is_staff": false
},
{
"id": 4,
"url": "http://testserver/users/4/",
"username": "foo3",
"email": "",
"is_staff": false
},
{
"id": 5,
"url": "http://testserver/users/5/",
"username": "foo4",
"email": "",
"is_staff": false
}
]
}
Recommended Posts