MoinMoin Logo
  • Comments
  • Immutable Page
  • Menu
    • Navigation
    • RecentChanges
    • FindPage
    • Local Site Map
    • Help
    • HelpContents
    • HelpOnMoinWikiSyntax
    • Display
    • Attachments
    • Info
    • Raw Text
    • Print View
    • Edit
    • Load
    • Save
  • Login

Navigation

  • Start
  • Sitemap

Upload page content

You can upload content for the page named below. If you change the page name, you can also upload content for another page. If the page name is empty, we derive the page name from the file name.

File to load page content from
Page name
Comment

  • Python
  • DjangoREST

Django REST framework

  • https://www.django-rest-framework.org/

Django REST framework is a powerful and flexible toolkit for building Web APIs.

Quickstart

  • Check django-rest-test

  • django shell python3 manage.py shell

  • Based on https://www.django-rest-framework.org/tutorial/quickstart/#quickstart

  • https://www.django-rest-framework.org/api-guide/viewsets/

  • https://www.django-rest-framework.org/api-guide/views/

   1 cd ~/tmp
   2 mkdir django-rest-test
   3 cd django-rest-test
   4 sudo apt install python3-venv
   5 python3 -m venv virtenv
   6 . virtenv/bin/activate
   7 pip install djangorestframework
   8 find . virtenv/
   9 django-admin startproject tutorial . 
  10 cd tutorial
  11 django-admin startapp quickstart
  12 cd ..
  13 python manage.py migrate # sync DB 
  14 python manage.py createsuperuser --email admin@example.com --username admin # create super user, pwd: 12345678 
  15 nano tutorial/quickstart/serializers.py
  16 nano tutorial/quickstart/views.py
  17 nano tutorial/urls.py
  18 nano tutorial/settings.py
  19 nano tutorials/quickstart/apps.py
  20 nano tutorials/quickstart/models.py
  21 
  22 python manage.py runserver
  23 # Starting development server at http://127.0.0.1:8000/
  24 curl -H 'Accept: application/json; indent=4' -u admin:12345678 http://127.0.0.1:8000/users/
  25 
  26 sqlite3 db.sqlite3
  27 .tables 
  28 select * from auth_user;
  29 .exit 
  30 
  31 python3 manage.py collectstatic
  32 mkdir -p static/others
  33 echo "aaaa" > static/others/test.txt
  34 
  35 curl -H 'Accept: application/json' -u admin:1234567 http://127.0.0.1:8000/helloworld/
  36 curl -H 'Accept: application/json' -u admin:12345678 http://127.0.0.1:8000/helloworldanon/
  37 curl http://127.0.0.1:8000/helloworldviewset/
  38 curl http://127.0.0.1:8000/static/others/test.txt
  39 curl -X POST -H "Content-Type:application/json" -u admin:12345678 -d "{\"task\":\"t2\"}"  http://127.0.0.1:8000/tasks/

tutorials/quickstart/apps.py

   1 from django.apps import AppConfig
   2 
   3 class QuickstartConfig(AppConfig):
   4     default_auto_field = 'django.db.models.BigAutoField'
   5     name = 'tutorial.quickstart'

tutorials/quickstart/models.py

   1 from django.db import models
   2 
   3 class Task(models.Model):
   4     created = models.DateTimeField(auto_now_add=True)
   5     task = models.CharField(max_length=128, blank=True, default='')
   6 """
   7 python manage.py makemigrations quickstart
   8 python manage.py migrate
   9 sqlite3 db.sqlite3
  10 .tables 
  11 # quickstart_task
  12 .dump quickstart_task 
  13 PRAGMA foreign_keys=OFF;
  14 BEGIN TRANSACTION;
  15 CREATE TABLE IF NOT EXISTS "quickstart_task" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "task" varchar(128) NOT NULL);
  16 COMMIT;
  17 .exit 
  18 """

tutorial/quickstart/serializers.py

   1 from django.contrib.auth.models import User, Group
   2 from rest_framework import serializers
   3 from tutorial.quickstart.models import Task
   4 
   5 class UserSerializer(serializers.HyperlinkedModelSerializer):
   6     class Meta:
   7         model = User
   8         fields = ['url', 'username', 'email', 'groups']
   9 
  10 
  11 class GroupSerializer(serializers.HyperlinkedModelSerializer):
  12     class Meta:
  13         model = Group
  14         fields = ['url', 'name']
  15 
  16 class TaskSerializer(serializers.ModelSerializer):
  17     class Meta:
  18         model = Task
  19         fields = ['id','task','created']

tutorial/quickstart/views.py

   1 import json
   2 from django.contrib.auth.models import User, Group
   3 from rest_framework import viewsets,permissions
   4 from tutorial.quickstart.serializers import UserSerializer, GroupSerializer
   5 from django.views.decorators.csrf import csrf_exempt
   6 from rest_framework.authentication import SessionAuthentication, BasicAuthentication
   7 from rest_framework.permissions import IsAuthenticated
   8 from rest_framework.response import Response
   9 from rest_framework.decorators import api_view, authentication_classes, permission_classes
  10 from rest_framework.views import APIView
  11 from tutorial.quickstart.models import Task
  12 from tutorial.quickstart.serializers import TaskSerializer
  13 from django.http import HttpResponse, JsonResponse
  14 from rest_framework.parsers import JSONParser
  15 
  16 class UserViewSet(viewsets.ModelViewSet):
  17     """
  18     API endpoint that allows users to be viewed or edited.
  19     """
  20     queryset = User.objects.all().order_by('-date_joined')
  21     serializer_class = UserSerializer
  22     permission_classes = [permissions.IsAuthenticated]
  23 
  24 
  25 class GroupViewSet(viewsets.ModelViewSet):
  26     """
  27     API endpoint that allows groups to be viewed or edited.
  28     """
  29     queryset = Group.objects.all()
  30     serializer_class = GroupSerializer
  31     permission_classes = [permissions.IsAuthenticated]
  32 
  33 
  34 @csrf_exempt
  35 @api_view(['GET'])
  36 @authentication_classes([SessionAuthentication, BasicAuthentication])
  37 @permission_classes([IsAuthenticated])
  38 def hello_world(request):
  39     """
  40     Function view
  41     """
  42     return Response({"message": "Hello world", "user": str(request.user)})
  43 
  44 
  45 class HelloWorldAnonView(APIView):
  46     def get(self, request, format=None):
  47         return Response({"message": "Hello world anonymous", "user": str(request.user)})
  48 
  49 
  50 class HelloWorldViewSet(viewsets.ViewSet):
  51     # authentication required
  52     permission_classes = [permissions.IsAuthenticated]
  53 
  54     def list(self, request):
  55         return Response({"message": "Hello world view set up and running " + str(request.user)})
  56 
  57 
  58 class TaskViewSet(viewsets.ModelViewSet):
  59     # ModelViewSet
  60     queryset = Task.objects.all().order_by("created")
  61     serializer_class = TaskSerializer
  62     permission_classes = [permissions.IsAuthenticated]
  63 
  64     # # authentication required
  65     # permission_classes = [permissions.IsAuthenticated]
  66 
  67     # def list(self, request):
  68     #     serializer = TaskSerializer(Task.objects.all(), many=True)
  69     #     return Response(serializer.data)
  70 
  71     # def create(self, request):
  72     #     payload = JSONParser().parse(request)
  73     #     serializer = TaskSerializer(data=payload)
  74     #     if serializer.is_valid():
  75     #         serializer.save()
  76     #         return Response(serializer.data, status=201)        

tutorial/urls.py

   1 from django.urls import include, path
   2 from rest_framework import routers
   3 from tutorial.quickstart import views
   4 
   5 router = routers.DefaultRouter()
   6 router.register(r'users', views.UserViewSet)
   7 router.register(r'groups', views.GroupViewSet)
   8 router.register(r'helloworldviewset', views.HelloWorldViewSet,basename="helloworldviewset")
   9 router.register(r'tasks', views.TaskViewSet,basename="tasks")
  10 
  11 # Wire up our API using automatic URL routing.
  12 # Additionally, we include login URLs for the browsable API.
  13 urlpatterns = [
  14     path('', include(router.urls)),
  15     path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
  16     path('helloworld/',views.hello_world),
  17     path('helloworldanon/',views.HelloWorldAnonView.as_view()),
  18 ]

tutorial/settings.py

   1 """
   2 Django settings for tutorial project.
   3 
   4 Generated by 'django-admin startproject' using Django 3.2.5.
   5 
   6 For more information on this file, see
   7 https://docs.djangoproject.com/en/3.2/topics/settings/
   8 
   9 For the full list of settings and their values, see
  10 https://docs.djangoproject.com/en/3.2/ref/settings/
  11 """
  12 
  13 from pathlib import Path
  14 import os
  15 import sys
  16 # Build paths inside the project like this: BASE_DIR / 'subdir'.
  17 BASE_DIR = Path(__file__).resolve().parent.parent
  18 
  19 # Quick-start development settings - unsuitable for production
  20 # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
  21 
  22 # SECURITY WARNING: keep the secret key used in production secret!
  23 SECRET_KEY = 'django-insecure-j8vs^2rq97)%g%v4fk-nl(3pho4ve)=6%&$**0++$p%v514r8r'
  24 
  25 # SECURITY WARNING: don't run with debug turned on in production!
  26 DEBUG = True
  27 
  28 ALLOWED_HOSTS = []
  29 
  30 
  31 # Application definition
  32 
  33 INSTALLED_APPS = [
  34     'django.contrib.admin',
  35     'django.contrib.auth',
  36     'django.contrib.contenttypes',
  37     'django.contrib.sessions',
  38     'django.contrib.messages',
  39     'django.contrib.staticfiles',
  40     'rest_framework',
  41     'tutorial.quickstart.apps.QuickstartConfig',
  42 ]
  43 
  44 MIDDLEWARE = [
  45     'django.middleware.security.SecurityMiddleware',
  46     'django.contrib.sessions.middleware.SessionMiddleware',
  47     'django.middleware.common.CommonMiddleware',
  48     'django.middleware.csrf.CsrfViewMiddleware',
  49     'django.contrib.auth.middleware.AuthenticationMiddleware',
  50     'django.contrib.messages.middleware.MessageMiddleware',
  51     'django.middleware.clickjacking.XFrameOptionsMiddleware',
  52 ]
  53 
  54 ROOT_URLCONF = 'tutorial.urls'
  55 
  56 TEMPLATES = [
  57     {
  58         'BACKEND': 'django.template.backends.django.DjangoTemplates',
  59         'DIRS': [],
  60         'APP_DIRS': True,
  61         'OPTIONS': {
  62             'context_processors': [
  63                 'django.template.context_processors.debug',
  64                 'django.template.context_processors.request',
  65                 'django.contrib.auth.context_processors.auth',
  66                 'django.contrib.messages.context_processors.messages',
  67             ],
  68         },
  69     },
  70 ]
  71 
  72 WSGI_APPLICATION = 'tutorial.wsgi.application'
  73 
  74 
  75 # Database
  76 # https://docs.djangoproject.com/en/3.2/ref/settings/#databases
  77 
  78 DATABASES = {
  79     'default': {
  80         'ENGINE': 'django.db.backends.sqlite3',
  81         'NAME': BASE_DIR / 'db.sqlite3',
  82     }
  83 }
  84 
  85 
  86 # Password validation
  87 # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
  88 
  89 AUTH_PASSWORD_VALIDATORS = [
  90     {
  91         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
  92     },
  93     {
  94         'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
  95     },
  96     {
  97         'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
  98     },
  99     {
 100         'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
 101     },
 102 ]
 103 
 104 
 105 # Internationalization
 106 # https://docs.djangoproject.com/en/3.2/topics/i18n/
 107 
 108 LANGUAGE_CODE = 'en-us'
 109 
 110 TIME_ZONE = 'UTC'
 111 
 112 USE_I18N = True
 113 
 114 USE_L10N = True
 115 
 116 USE_TZ = True
 117 
 118 
 119 # Static files (CSS, JavaScript, Images)
 120 # https://docs.djangoproject.com/en/3.2/howto/static-files/
 121 
 122 STATIC_URL = '/static/'
 123 STATIC_ROOT = os.path.join(BASE_DIR, 'static')
 124 STATICFILES_DIRS = (
 125     ("others", os.path.join(STATIC_ROOT,'others')),
 126 )
 127 
 128 # Default primary key field type
 129 # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
 130 
 131 DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
 132 
 133 REST_FRAMEWORK = {
 134     'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
 135     'PAGE_SIZE': 10
 136 }

Queryset

  • https://docs.djangoproject.com/en/3.2/ref/models/querysets/#queryset-api-reference

Foreign keys and related names, _set

Instance members in model instances are created based on identified relations. Usually those members end with _set.

  • https://docs.djangoproject.com/en/3.2/ref/models/fields/#foreignkey

A many-to-one relationship. Requires two positional arguments: the class to which the model is related and the on_delete option.
  • https://docs.djangoproject.com/en/3.2/topics/db/models/#be-careful-with-related-name-and-related-query-name

If you don’t specify a related_name attribute for a field in an abstract base class, the default reverse name will be the name of the child class followed by '_set', just as it normally would be if you’d declared the field directly on the child class. For example, in the above code, if the related_name attribute was omitted, the reverse name for the m2m field would be childa_set in the ChildA case and childb_set for the ChildB field.

Related manager

  • https://docs.djangoproject.com/en/3.2/ref/models/relations/#related-objects-reference

A “related manager” is a manager used in a one-to-many or many-to-many related context.

  • MoinMoin Powered
  • Python Powered
  • GPL licensed
  • Valid HTML 4.01