(Ich habe ein Tag namens onefile erstellt, weil ich manchmal die problematischen Framework-Funktionen mit einer Datei ausprobieren möchte. Sie können es ohne Erlaubnis erstellen. Ich weiß nicht, ob es so ist.)
Django Rest Framework ist ein Framework, das auf Django basiert. Dies ist praktisch beim Erstellen einer REST-API. Es ist mühsam, die bereitgestellten Funktionen zu überprüfen. Schließlich ist das Lesen des internen Quellcodes zum Verständnis des Verhaltens oft einfacher als das Lesen der Dokumentation. Es gibt keinen Verlust, selbst wenn Sie eine Umgebung erstellen, in der Sie die Funktionen einfach ausprobieren können.
Sie können die Funktionen von django restframework mit dem folgenden Code ausprobieren. (Sie können es überspringen, ohne es sorgfältig zu lesen)
#Die Geschichte der Erstellung dieses Verknüpfungsmoduls
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)
Vorsichtsmaßnahmen und Erklärungen zur Verwendung.
Da es von der später erstellten shortcut.py
abhängt, muss es die folgende Struktur haben. (Natürlich können Sie das Paket ernst machen)
.
├── shortcut.py
└── view-sample1.py #Datei, die Sie versuchen möchten
Das Hinzufügen von view-sample1.py
und -
ist als Python-Modulname ungeeignet. (Ich persönlich gebe einen unangemessenen Dateinamen an, weil ich beim Versuch, von anderen zu importieren, einen Importfehler möchte, der jedoch wenig Sinn macht.)
Aufgrund des schlechten Designs von Django ist es notwendig, auf die Reihenfolge der Einfuhr zu achten. Die Reihenfolge und Position der folgenden Codes muss beachtet werden.
from shortcut import App # shorthand
from shortcut import do_get, do_post, do_delete
#Vor dem Importieren des restlichen Frameworks sind verschiedene Einstellungen erforderlich
app = App()
app.setup(apps=[__name__], root_urlconf=__name__)
#Importieren Sie Modell- und Restframework-Module
from django.contrib.auth.models import User
from rest_framework import routers, serializers, viewsets
Sobald Sie das Modul des Django-Rest-Frameworks importieren, wird möglicherweise eine Fehlermeldung angezeigt, z. B. die Notwendigkeit, Django festzulegen. Daher müssen Sie zuvor verschiedene Einstellungen vornehmen. Wenn Sie "urls.py" oder "django app" trennen möchten, ändert sich das Argument von "app.setup ()". Da in diesem Artikel beschrieben wird, wie Sie mit einer Datei versuchen, können Sie dies mit __name__
beheben.
Dies ist eine Funktion des Django-Rest-Frameworks, daher werde ich es nicht im Detail erklären. Siehe Dokumentation usw.
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)
Grundsätzlich stellt Serialier die Ausgabedarstellung und Variation des Modells bereit, Viewset verarbeitet eine Reihe von Ansichten mit Serialiezer, und wenn Sie das Viewset im Router registrieren, können Sie verschiedene REST-APIs verwenden.
Übrigens habe ich vergessen. Wenn Sie es mit einer Datei versuchen, müssen Sie "__meta __. App_label" festlegen, um die "Django-App" zu bestimmen, zu der das zu definierende Modell gehört. Zum Beispiel kann es wie folgt definiert werden.
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__
Wenn Sie es mit der Option "--run-server" starten, funktioniert es tatsächlich als App. Da die durchsuchbare API ebenfalls aktiviert ist, können Sie mit einem Browser darauf zugreifen, einen Wert in das Formular eingeben und GET / POST / PUT / DELETE ausprobieren. Intern nennt es nur "Runserver" von "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.
Da das zu verwendende Modell selbst so eingestellt ist, dass es in der speicherinternen Datenbank von sqlite registriert wird, muss jedes Mal eine Tabelle generiert werden. Es wird unten gemacht.
app.create_table(User)
Bei Ausführung ohne Argumente wird das Ausführungsbeispiel von django.test.client.Client
angezeigt. Im obigen Beispiel wird angenommen, dass "main_client ()" aufgerufen wird, aber nicht geschrieben wird. Schreiben Sie beispielsweise wie folgt.
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/")
Das Ausführungsergebnis ist wie folgt. (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 sieht folgendermaßen aus: Diese Erklärung ist mühsam, deshalb werde ich es nicht tun.
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("```")
Sie können beispielsweise die Paginierungsfunktion ausprobieren, indem Sie die folgenden Änderungen vornehmen.
--- 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.
Listenanzeige mit 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