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 (; ∀ ;)
Die Gesamtzeit betrug ca. 6 Stunden, einschließlich der Zeit für Google. Bitte von der Anleitung.
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).
OS | macOS Chatalina version 10.15.4 |
Sprache | Python, Java |
Rahmen | Django REST framework |
Klicken Sie hier, um einen Link zum gesamten Django REST-Framework zu erhalten (https://www.django-rest-framework.org/).
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.
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',
),
}
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.
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. .. ..
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.
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