[PYTHON] Erstellen Sie eine API mit Django

Einführung

Hallo Leute! Hallo, guten Abend oder gute Nacht!

Hallo, ich bin's. Das ist Takurinton.

Diesmal ist es so, als würde man mit Django eine API erstellen und sie treffen. Als Hintergrund gab es ein Problem, das ich nicht implementieren konnte, ohne so etwas in einem bestimmten Fach unserer Universität zu tun, also habe ich das Gefühl, dass ich es ein wenig tun werde. Nun, es war ziemlich schwer, weil ich aus einem Zustand der Unwissenheit stammte. Es ist eine kostenlose Aufgabe, also völlig selbstzerstörend (; ∀ ;)

Voraussetzungen

Benötigte Zeit

Die Gesamtzeit betrug ca. 6 Stunden, einschließlich der Zeit für Google. Bitte von der Anleitung.

Hintergrund

Ich habe es geschafft, indem ich die EC-Site umgestaltet habe, die ursprünglich durch Outsourcing erstellt wurde. Ich sollte die Site, die aktualisiert wird, jedoch nicht zerstören. Daher dachte ich, es wäre einfach, eine andere Umgebung in Docker zu erstellen und eine virtuelle Umgebung mit Docker-Compose zu erstellen. Ich denke, dass sich nur die Datenbank ändern wird, ob Sie Docker verwenden oder nicht, daher werde ich diesen Teil weglassen (ich werde die Details bald in meinem persönlichen Blog schreiben).

Umgebung

OS macOS Chatalina version 10.15.4
Sprache Python, Java
Rahmen Django REST framework

Technologie verwendet

Klicken Sie hier, um einen Link zum gesamten Django REST-Framework zu erhalten (https://www.django-rest-framework.org/).

erstellen! !! !!

Verfassung

Ursprünglich waren die Datenbank und die Logik solide, sodass keine Wartung erforderlich war.

Die diesmal erstellte API erfasst Bestellinformationen. Als Bild

Ich möchte den Hit bekommen, also habe ich ihn entsprechend implementiert.

Die diesbezügliche Datenbank lautet wie folgt.

models.py


class CustomUserManager(UserManager):
    use_in_migrations = True
    def _create_user(self, email, password=None, zip_code=None, address1=None, address2=None, address3=None,  **extra_fields):
        if not email:
            raise ValueError('E-Mail ist obligatorisch und keine Deckung')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        phone_number_regex = RegexValidator(regex=r'^[0-9]+$', message = ("Tel Number must be entered in the format: '09012345678'. Up to 15 digits allowed."))
        phone_number = models.CharField(validators=[phone_number_regex], max_length=15, verbose_name='Telefonnummer')
        zip_code = models.CharField(max_length=8)
        address1 = models.CharField(max_length=40)
        address2 = models.CharField(max_length=40)
        address3 = models.CharField(max_length=40, blank=True)
        user.save(using=self._db)
        return email



    def create_user(self, request_data, **kwargs):
        if not request_data['email']:
            raise ValueError('Users must have an email address.')

        user = self.model(
            email=request_data['email'],
            first_name=request_data['first_name'], 
            last_name=request_data['last_name'], 
            # password=request_data['password'], 
            zip_code=request_data['zip_code'],
            address1=request_data['address1'], 
            address2=request_data['address2'], 
            address3=request_data['address3'], 
        )

        user.set_password(request_data['password'])
        user.save(using=self._db)
        return user

    def create_superuser(self, email, phone_number=None, password=None, zip_code=None, address1=None, address2=None, address3=None,  **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')
        return self._create_user(email, password, **extra_fields)


class User(AbstractBaseUser, PermissionsMixin):
    #username = models.CharField(_('username'), max_length=20, unique=True)
    email = models.EmailField(_('email address'), unique=True)
    first_name = models.CharField(_('first name'), max_length=30)
    last_name = models.CharField(_('last name'), max_length=150)
    zip_code = models.CharField(max_length=8)
    address1 = models.CharField(max_length=40)
    address2 = models.CharField(max_length=40)
    address3 = models.CharField(max_length=40, blank=True)
    phone_number_regex = RegexValidator(regex=r'^[0-9]+$', message = ("Tel Number must be entered in the format: '09012345678'. Up to 15 digits allowed."))
    phone_number = models.CharField(validators=[phone_number_regex], max_length=15, verbose_name='Telefonnummer', null=True, blank=True)

    is_staff = models.BooleanField(
        _('staff status'),
        default=False,
        help_text=_(
            'Designates whether the user can log into this admin site.'),
    )
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            'Designates whether this user should be treated as active. '
            'Unselect this instead of deleting accounts.'
        ),
    )
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

    objects = CustomUserManager()
    EMAIL_FIELD = 'email'
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []


    def user_has_perm(self, user, perm, obj):
        return _user_has_perm(user, perm, obj)

    def has_perm(self, perm ,obj=None):
        return _user_has_perm(self, perm, obj=obj)
    
    def has_module_perms(self, app_label):
        return self.is_staff

    def get_short_name(self):
        return self.first_name

    class Meta:
        # db_table = 'api_user'
        swappable = 'AUTH_USER_MODEL'

class Company(models.Model):
    name = models.CharField(max_length=255)
    introduction = models.TextField(max_length=65536)
    postal_code = models.CharField(max_length=8)
    company_image = models.ImageField()
    homepage = models.CharField(max_length=255, null=True, blank=True)
    images = models.BooleanField(verbose_name='', default=False)
    place = models.CharField(max_length=255)

    def __str__(self):
        return str(self.name)


class Product(models.Model):
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    contents = models.CharField(max_length=255)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    product_image = models.ImageField()
    option = models.CharField(max_length=255, null=True, blank=True, default=None)
    price = models.IntegerField()
    def __str__(self):
        return str(self.name)

class Cart(models.Model):
    cart_id = models.IntegerField(null=True, blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
    is_active = models.BooleanField(default=True)
    pub_date = models.DateTimeField(null=True, blank=True)

    def __str__(self):
        return str(self.cart_id)



class UserInfomation(models.Model):
    cart = models.ForeignKey(Cart, on_delete=models.CASCADE, blank=True, null=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
    day = models.CharField(max_length=255, default=None)
    time = models.CharField(null=True, blank=True, max_length=255,  default=None)
    status = models.BooleanField(default=False, null=True, blank=True)
    total = models.IntegerField(null=True)
    remark = models.TextField(max_length=65535, null=True, blank=True)
    pub_date = models.DateTimeField(default=now)

    def __str__(self):
        return str(self.user)


class OrderItems(models.Model):
    user = models.ForeignKey(UserInfomation, on_delete=models.CASCADE)
    cart = models.ForeignKey(Cart, on_delete=models.CASCADE, blank=True, null=True)
    item = models.ForeignKey(Product, on_delete=models.CASCADE, blank=True, null=True)
    number = models.IntegerField(null=True)
    price = models.IntegerField(null=True)
    total = models.IntegerField(null=True)

Es gibt andere Tabellen, aber dieses Mal werde ich sie weglassen, weil ich es genau damit machen kann.

ich werde machen

Vorbereitung

Wenn Sie das restliche Framework nicht installiert haben, installieren Sie es zunächst.

pip install djangorestframework

Fügen Sie als Nächstes die folgenden Einstellungen zu settings.py hinzu.

settings.py


...  

INSTALLED_APPS = [
    ...
    'rest_framework',
]

...



JWT_AUTH = {
    'JWT_VERIFY_EXPIRATION': False, #Token-Persistenz
    'JWT_AUTH_HEADER_PREFIX': 'JWT',
}


REST_FRAMEWORK = { 
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),  
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),  
    'NON_FIELD_ERRORS_KEY': 'detail',
    'TEST_REQUEST_DEFAULT_FORMAT': 'json', 
    'DEFAULT_FILTER_BACKENDS': (
        'django_filters.rest_framework.DjangoFilterBackend', 
    ), 
}



Anmeldefunktion

Hier erstellen wir eine Funktion, um sich bei einem vorhandenen Benutzer anzumelden. Dieses Mal werden wir alle Anfragen authentifizieren. Dies ist erforderlich, da nur angemeldete Benutzer arbeiten können. Erstellen Sie zunächst einen Endpunkt.

project_name/urls.py


from django.conf.urls import url

from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
    url(r'^login_/', obtain_jwt_token),
    ..., 
]

Durch Hinzufügen dieses Endpunkts wird die Anmeldefunktion abgeschlossen. Voraussetzung ist, dass Sie eine Datenbank erstellen. get_jwt_token gibt ein Token zur Authentifizierung zurück, wenn Sie auf diesen Endpunkt zugreifen.

Ich möchte mich als bestehender Benutzer anmelden. Ich werde Ipython im experimentellen Stadium verwenden (weil es einfach ist)

In [1]: import requests
In [2]: import json
In [3]: data = {'email': '[email protected]', 'password': 'hogehoge'}
In [4]: r = requests.post('localhost:8000/login_/', data=data)
In [5]: print(r.json())
Out[5]: {'token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo5LCJ1c2VybmFtZSI6ImIxODA2NDI5QGdtYWlsLmNvbSIsImV4cCI6MTU5NDc5OTMwNCwiZW1haWwiOiJiMTgwNjQyOUBnbWFpbC5jb20ifQ.Torhy69ZyKMOOxQUUv3Ebn9V6wqSwUlsQUD5IPUaDJA'}

Ein langer JSON wird so zurückgegeben. Derzeit gibt es in Python so etwas wie json.dumps (dict), das das Wörterbuch in JSON konvertiert. Wenn Sie dies jedoch tun, wird eine Fehlermeldung angezeigt. Hier werden nur Daten vom Typ dikt übergeben. Bitte bewahren Sie dieses zurückgegebene Token auch auf, da Sie es später verwenden werden. Die beim Anmelden verwendeten Daten sind die E-Mail-Adresse und das Kennwort, die die Primärschlüssel sind. Wenn Sie nicht wissen, was es ist, lesen Sie den Code in models.py.

Nebenbei können Sie in Python-Anforderungen einen Textkörper in Daten und einen Header in Header einfügen. Mit r.json () können Sie die Antwort in einen Diktattyp konvertieren und in ein benutzerfreundliches Formular konvertieren. Anfragen und JSON sind ziemlich dicht. Es ist dicht. Es ist dicht.

Benutzerdefiniertes JSON

Als nächstes werde ich den für mich angepassten JSON zurückgeben. Persönlich bin ich hier gestolpert.

Erstens Serializer und generische Ansichten Ich dachte, es wäre besser, es mit / generic-views / #genericapiview zu implementieren, aber anscheinend ist dies ein benutzerdefinierter JSON (diese können nur Felder zurückgeben, die in einer einzelnen Tabelle vorhanden sind). Ich kann nicht zurückkehren, also habe ich die Methode geändert. Ich habe lange gebraucht, um zur aktuellen Methode zu gelangen, das ist also mein Spiegelbild.

Wenn Sie einen benutzerdefinierten JSON zurückgeben möchten, benötigen Sie keinen Serializer. Schreiben Sie ihn daher direkt in views.py. Der Endpunkt ist in urls.py beschrieben.

urls.py



from django.urls import path
from . import views


urlpatterns = [
...
path('get_shop_view', views.ShopView.as_view()), #Füge das hinzu
]

views.py



from django.http import HttpResponse
from rest_framework import generics

class ShopView(generics.ListCreateAPIView):
    # list(self, request, *args, **kwargs)Kann benutzerdefinierte JSON mithilfe von generieren
    def list(self, request, *args, **kwargs):
        #Liste von JSON, um endlich zurückzukehren
        return_list = list()
        try:
            user_info = UserInfomation.objects.all() #Holen Sie sich alle Benutzer mit Kauferfahrung
            for i in user_info:
                order = OrderItems.objects.filter(user=i) #Geben Sie den Benutzer an
                shop = order[0].item.company.name #Firma angeben

                #Produktliste abrufen
                order_items = dict()
                for i in order:
                    order_items[i.item.name] = {
                                                'price': i.item.price, #Preis
                                                'images': str(i.item.product_image) #Bild URL
                                                } 


                total = sum([i.total for i in order]) #Gesamtgebühr. Ruft die Summe der durch die Listeneinbeziehung generierten Liste ab

                date_time_ = UserInfomation.objects.get(cart=i.cart)
                date_time = date_time_.day + date_time_.time #Holen Sie sich die gewünschte Lieferzeit
                
                #Fügen Sie diese Daten in die gesamte Liste ein
                return_list.append(
                    {
                        'user': str(i.user),   #Benutzerpost
                        'shop': shop,          #Speichern Sie dort, wo Sie bestellt haben
                        'order': order_items,  #Liste der bestellten Produkte
                        'total': total,        #Gesamtgebühr
                        'datetime': date_time, #Gewünschte Lieferzeit
                    }
                )    
        #Gibt eine leere Liste zurück, wenn ein Fehler auftritt
        except:
            pass

        return Response(
            return_list
        )

Nach dem Erstellen werde ich eine Get-Anfrage an den zuvor erstellten Endpunkt senden

In [1]: {'Content-Type': 'application/json',
 'Authorization': 'JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo5LCJ1c2VybmFtZSI6ImIxODA2NDI5QGdtYWlsLmNvbSIsImV4cCI6MTU5NDc5OTMwNCwiZW1haWwiOiJiMTgwNjQyOUBnbWFpbC5jb20ifQ.Torhy69ZyKMOOxQUUv3Ebn9V6wqSwUlsQUD5IPUaDJA'}
In[2]: order_list = requests.get('http://localhost:8000/get_shop_view', headers=headers)
In [3]: order_list.json()
Out[3]:
[{'user': '[email protected]',
  'shop': 'Speichern B.',
  'order': {'Hamburger': {'price': 1000,
    'images': 'IMG_4145_ykxb9h'}},
  'total': 1000,
  'datetime': '14. Juli 2020 Jetzt'},
 {'user': '[email protected]',
  'shop': 'Speichern B.',
  'order': {'Hamburger': {'price': 1000,
    'images': 'IMG_4145_ykxb9h'},
   'Curry': {'price': 2,
    'images': '11967451898714_y6tgch'}},
  'total': 2002,
  'datetime': '14. Juli 2020 Jetzt'},
 {'user': '[email protected]',
  'shop': 'Speichern B.',
  'order': {'Eintopf': {'price': 11111,
    'images': 'IMG_4900_oyb5ny'},
   'Hamburger': {'price': 1000,
    'images': 'IMG_4145_ykxb9h'},
   'Kaffee': {'price': 199,
    'images': '54490_jawqyl'},
   'Curry': {'price': 2,
    'images': '11967451898714_y6tgch'},
   'Pfannkuchen': {'price': 100,
    'images': 'tweet_p7chgi'},
   'Takurinton': {'price': 100,
    'images': 'npyl13'}},
  'total': 24220,
  'datetime': '16. Juli 2020 Jetzt'}]

Dies ist die, die ich im Voraus in den Wagen gelegt hatte, aber sie kam sicher zurück! !! !! glücklich ~! !! !! Bisher dauerte es ungefähr 5 Stunden und 45 Minuten. .. ..

Versuchen Sie es mit Java

Da es sich bei dem Bericht um Java handelt, wollte ich ihn in Java anzeigen können, also habe ich ihn gegoogelt und es war überraschend einfach. Ich bin ein bisschen glücklich, weil ich dachte, es sei eine schwierige Sprache. .. .. LOL

Test.java


import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandler;
import java.nio.charset.StandardCharsets;
 
public class Test{
	public static void main(String[] args){
		try {
			HttpRequest request = HttpRequest
					.newBuilder(URI.create("http://localhost:8000/get_shop_view"))
                    .header("Content-Type", "application/json")
                    .header("Authorization", "JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo5LCJ1c2VybmFtZSI6ImIxODA2NDI5QGdtYWlsLmNvbSIsImV4cCI6MTU5NDc5OTMwNCwiZW1haWwiOiJiMTgwNjQyOUBnbWFpbC5jb20ifQ.Torhy69ZyKMOOxQUUv3Ebn9V6wqSwUlsQUD5IPUaDJA")
                    .GET()
					.build();
 
			BodyHandler<String> bodyHandler = HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8);
			HttpResponse<String> response = HttpClient.newBuilder().build().send(request, bodyHandler);
            
            String body = response.body();
            System.out.println(body);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Der Code ist noch lang, aber akzeptabel. Es scheint eine Haltung des Schreibens in HttpRequest zu sein. Sie können das gleiche Token in der Kopfzeile verwenden, das Sie zuvor erhalten haben. Ich verstehe es nicht wirklich, aber ...

Kompilieren und ausführen.

(base) Hogehoge:working takurinton$ javac Test.java
(base) Hogehoge:working takurinton$ java Test
[{'user': '[email protected]',
  'shop': 'Speichern B.',
  'order': {'Hamburger': {'price': 1000,
    'images': 'IMG_4145_ykxb9h'}},
  'total': 1000,
  'datetime': '14. Juli 2020 Jetzt'},
 {'user': '[email protected]',
  'shop': 'Speichern B.',
  'order': {'Hamburger': {'price': 1000,
    'images': 'IMG_4145_ykxb9h'},
   'Curry': {'price': 2,
    'images': '11967451898714_y6tgch'}},
  'total': 2002,
  'datetime': '14. Juli 2020 Jetzt'},
 {'user': '[email protected]',
  'shop': 'Speichern B.',
  'order': {'Eintopf': {'price': 11111,
    'images': 'IMG_4900_oyb5ny'},
   'Hamburger': {'price': 1000,
    'images': 'IMG_4145_ykxb9h'},
   'Kaffee': {'price': 199,
    'images': '54490_jawqyl'},
   'Curry': {'price': 2,
    'images': '11967451898714_y6tgch'},
   'Pfannkuchen': {'price': 100,
    'images': 'tweet_p7chgi'},
   'Takurinton': {'price': 100,
    'images': 'npyl13'}},
  'total': 24220,
  'datetime': '16. Juli 2020 Jetzt'}]

Ich werde sicher zurückkehren. React und Vue sind aufgrund des Browsers ärgerlicher, aber Java ist einfach, da es in der Befehlszeile ausgeführt wird.

Zusammenfassung

Tatsächlich gibt es viele Dinge wie Benutzererstellung, Benutzerinformationserfassung, Geschäftsinformationserfassung, Produktliste, die das Geschäft hat, außer dem, was ich hier geschrieben habe. Da es hier viele Teile gibt, die von einer Tabelle abhängen, ist das Erstellen durch Angabe von Feldern schneller als durch benutzerdefinierte Felder. Daher ist es wichtig, diese ordnungsgemäß zu verwenden. Ich bin es leid, Java zu berühren, also lasse ich es heute hier. LOL

Ich konnte es auch in ungefähr 6 Stunden implementieren, aber es scheint ein langer Weg zu sein, weil ich immer mehr damit spielen muss.

Es ist schwer, alle Aufgaben in der Online-Klasse mit Corona-Virus zu bekommen! Willst du testen! College-Studenten, die darüber nachdenken! Lassen Sie uns gemeinsam so viel wie das Koronavirus studieren und diese Situation überwinden! Ich werde noch 2 Wochen mein Bestes geben! !!

Recommended Posts

Erstellen Sie eine API mit Django
Erstellen Sie mit Django Updateview einen Update-Bildschirm
[Python] Erstellen Sie schnell eine API mit Flask
Erstellen Sie schnell einen API-Server mit Python + Falcon
Erstellen Sie eine Umgebung mit virtualenv
Erstellen Sie eine Homepage mit Django
Qiita API Oauth mit Django
Laden Sie ein Django-Modul mit einem Interpreter
Erstellen Sie Awaitable mit der Python / C-API
[AWS] API mit API Gateway + Lambda erstellen
Erstellen Sie eine API mit hug mit mod_wsgi
Erstellen Sie eine Altersgruppe mit Pandas
Hinweis: Senden Sie eine E-Mail mit Django
GraphQL-API mit graphene_django in Django
Erstellen Sie mit Django einen Datei-Uploader
Erstellen Sie eine Authentifizierungsfunktion mit django-allauth und CustomUser in Django
Erstellen Sie eine Web-API, die Bilder mit Django liefern kann
Erstellen einer Todo-App mit Django ① Erstellen Sie eine Umgebung mit Docker
Erstellen Sie mit Django eine API für die soziale Integration von Smartphone-Apps
Erstellen Sie eine Anwendung, indem Sie mit Pygame klassifizieren
Erstellen Sie eine RESTful-API mit dem Django Rest Framework
Erstellen Sie automatisch eine Python-API-Dokumentation mit Sphinx
Erstellen Sie mit PySimpleGUI einen Bildverarbeitungs-Viewer
Erstellen Sie mit der AWS-API einen Alias für Route53 zu CloudFront
Durchsuchen Sie eine vorhandene externe Datenbank mit Django
Internationalisierung mit Django
Erstellen Sie schnell eine Excel-Datei mit Python #python
Erstellen Sie eine Anwendung mit der Spotify-API
Erstellen Sie mit Vagrant (Ubuntu 16.04) eine Umgebung für Django x Apache x mod_wsgi.
Erstellen der ersten App mit Django Startprojekt
CRUD mit Django
Generieren Sie eine add-in-fähige Excel-Instanz mit xlwings
Erstellen Sie eine englische Wort-App mit Python
Erstellen Sie einen Seiten- / Todo-Block mit der Notion-API
Erstellen Sie eine REST-API, um dynamodb mit dem Django REST Framework zu betreiben
Erstellen Sie mit cx_Freeze eine aktualisierbare MSI-Datei
[AWS SAM] Erstellen Sie eine API mit DynamoDB + Lambda + API Gateway
Erstellen Sie ein akademisches Programm mit Kombinationsoptimierung
Erstellen Sie eine Bildkompositions-App mit Flask + Pillow
Erstellen Sie mit Django ein Dashboard für Netzwerkgeräte!
Erstellen Sie mit Docker eine Umgebung aus Nginx + uWSGI + Python (Django)
Erstellen Sie ein Bild mit Zeichen mit Python (Japanisch)
Erstellen Sie mit Django eine Hallo-Welt-Anwendung mit nur einer Datei
So erstellen Sie eine Rest-API in Django
Authentifizieren Sie Google mit Django
Django 1.11 wurde mit Python3.6 gestartet
Laden Sie Dateien mit Django hoch
Erstellen Sie einen Django-Zeitplan
PDF mit Django ausgeben
Markdown-Ausgabe mit Django
Erstellen Sie eine API zum Konvertieren von PDF-Dateien in TIF-Bilder mit FastAPI und Docker
Verwenden Sie Gentelella mit Django
Twitter OAuth mit Django
Erste Schritte mit Django 1
Mail mit Django senden
Datei-Upload mit Django
Erstellen Sie mithilfe der COTOHA-API eine App, die gut mit Berichten von Personen funktioniert
Extrudieren Sie mit der Fusion360-API
Erstelle Spiele mit Pygame