-Ich hatte ein sehr falsches Verständnis des Befehls "Docker-Compose Run", also habe ich ihn korrigiert und den Schreibstil geändert, um den Befehl "Docker Exec" als Alternative zu verwenden.
Nachdem wir uns mit den Grundlagen von Python befasst haben, werden wir eine Umgebung erstellen, um uns an Django zu gewöhnen. Der Artikel des Planers enthält nur ein Tutorial zu den Grundlagen von Django. Dies ist die Ausgabe, wenn Sie das tun.
Artikel, der die Systementwicklung mit Django (Python) _Introduction ermöglicht
Erstellen Sie eine Django-Umgebung mit Docker-Compose (MariaDB + Nginx + uWSGI) Python3.6 + NGINX + MariaDB10 + uWSGI Django Environment Greedy Set mit Docker-Compose
Es wurde in der folgenden Umgebung unter Bezugnahme auf die beiden oben genannten Artikel und die Umgebung erstellt.
・ Windows10-Startseite ・ Docker Version 19.03.1 (Docker Toolbox-Spezifikation) ・ VirtualBox 6.0.16 ・ Python3.8 ・ Django 3 ・ Mariadb 10.1 ・ Nginx 1.13
.
├── db
│ ├── data
│ └── sql
│ └── init.sql
├── docker-compose.yml
├── nginx
│ ├── conf
│ │ └── app_nginx.conf
│ ├── log
│ └── uwsgi_params
├── python
│ ├── Dockerfile
│ └── requirements.txt
├── src
│ └── project
│ ├── app
│ │ └── __init__.py
│ │ └── settings.py
│ │ └── urls.py
│ │ └── uwsgi.log
│ │ └── views.py
│ │ └── wsgi.py
│ │
│──── ──├── migrations
│ │
│ ├── project
│ │ └── __init__.py
│ │ └── settings.py
│ │ └── urls.py
│ │ └── uwsgi.log
│ │ └── views.py
│ │ └── wsgi.py
│ │
│ └── manage.py
│ └── uwsgi.ini
└── static
Dockerfile
FROM python:3.8-alpine
ENV PYTHONUNBUFFERED 1
ENV PYTHONIOENCODEING utf-8
ENV APP_PATH code
# /$APP_Es ist auch mit PARH möglich, aber diesmal wird es beschrieben, weil es Fehlervermeidung und Übung ist.
WORKDIR /code
# /Code ist$APP_Auch mit PATH möglich
COPY ./requirements.txt /$APP_PATH
RUN apk add --no-cache --virtual .build-deps bash gcc musl-dev libffi-dev \
g++ libgcc libstdc++ libxml2-dev libxslt-dev openssl-dev curl \
&& apk add --no-cache --virtual --update-cache\
jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev \
mariadb-dev mariadb-connector-c-dev \
&& pip install cython && pip install -U pip && pip install -r requirements.txt
RUN rm -rf /var/cache/apk/* && \
rm -rf /tmp/*
Lassen Sie uns hier noch einmal einen Rückblick geben. Was FROM und ENV betrifft, werde ich den ersten Auftritt wegnehmen, da er wie ein Zauber ist. Erstens die Notation alpine. Es ist wie bei Alpine Linux, einer ultraleichten Version von Linux. Und da Docker wie ein Meisterwerk von Linux ist, ist der Versuch, das Gewicht des Bildes in Docker auf dieser Grundlage zu reduzieren, vorerst wie eine alpine Notation. .. Es gibt auch eine -slim-Notation, und mit -alpine scheinen einige Pakete wie Numpy beim Erstellen mit Docker ein Problem zu haben. Dies liegt daran, dass die Verarbeitung vom Typ C in ein solches Paket integriert ist, das Bild der alpinen Notation jedoch Lassen Sie uns vorerst nur verstehen, dass die alpine Notation in Docker das Bild heller macht.
Als nächstes ist WORKDIR und COPY, WORKDIR die Spezifikation des Arbeitsverzeichnisses in der virtuellen Umgebung. Später werde ich es in docker-compose.yml festlegen, aber dieses Mal werde ich den src-Ordner auf der Host-Seite freigeben und den Code-Ordner der virtuellen Umgebung, dh den Projektordner der Anwendung, in diesem Ordner erweitern .. COPY ist eine Anweisung zum Kopieren der im Pfad vorhandenen Dateien in den von $ APP_PATH angegebenen Ordner in der virtuellen Umgebung. Da der Pfad auf der Hostseite basierend auf dem Verzeichnis angegeben wird, in dem sich die Docker-Datei befindet, dh der Speicherort, der aus der Docker-Datei einen Schritt nach unten vom übergeordneten Ordner entfernt ist, wird er wie oben beschrieben angegeben.
Installieren Sie danach verschiedene Pakete mit RUN, hauptsächlich um Fehler in der C-Verarbeitung zu vermeiden, die durch die Verwendung von alpine (bis zu gcc ~ libxslt-dev) und Konnektoren für die Verbindung mit MariaDB verursacht werden. Fügen Sie schließlich cython (beschleunigtes Python mit C-Sprach-Know-how) mit pip hinzu, aktualisieren Sie pip und installieren Sie das in den Anforderungen.txt beschriebene Paket.
requirements.txt
Django==3.0
django-bootstrap4
flake8==3.7.9
ipython==7.10.1
mysqlclient==1.4.6
Pillow==6.2.1
uwSGI==2.0.18
dj-static
whitenoise
Ich habe es als Testversion aufgenommen, und Django, django-bootstrap4 und mysqlclient reichen aus, um es zu Beginn des Studiums wie ich zu verwenden. Da uwSGI als Referenzquelle implementiert ist, werde ich es versuchen, weil es eine große Sache ist.
Ein Modul zum einfachen Schreiben eines Bootstrap-Registrierungs- / Korrekturformulars in Python. Um die detaillierte Verwendung zu erläutern, müssen Sie den Mechanismus von View in Django etwas genauer verstehen. Fahren Sie also mit dem Verständnis fort, dass Sie Bootstrap 4 mit Django einbeziehen sollten, wenn Sie es verwenden.
mysqlclient
Module, die benötigt werden, um mit Python eine Verbindung zu MySQL herzustellen
Einfach ausgedrückt handelt es sich um einen AP-Server, dh einen Anwendungsserver. Bisher habe ich mit einem flauschigen Verständnis gelernt, dass ich mich vorerst auf den Webserver und den Anwendungsserver vorbereiten muss. Dieses Mal hatte ich die Gelegenheit, in die Technologie namens uWSGI einzusteigen, und habe versucht, anhand des folgenden Referenzartikels etwas tiefer zu graben.
Unterschiede zwischen Webserver und Anwendungsserver bei der Rails-Entwicklung (Übersetzung) Einführung in uWSGI Über "uWSGI" und Anwendungsserver Ich werde den Unterschied zwischen dem Webserver und dem Anwendungsserver auf leicht verständliche Weise erklären Welche Rolle spielt der AP-Server? Lassen Sie uns den Unterschied zum Webserver verstehen.
Wenn ich es zusammenstelle
・ Was ist WSGI?
→ Abkürzung für "Web Server Gateway Interface", eine Kommunikationsregel zwischen einer Python-Webanwendung und einem Webserver ... Mit anderen Worten, ein Protokoll. Natürlich ist die Kommunikation ohne ein Protokoll nicht möglich, aber anscheinend besteht das Problem darin, dass die Unterstützung des Frameworks und die Nichtunterstützung für Webserver gemischt sind. Wenn Sie in Python auf diese Weise ein gemeinsames Protokoll erstellen, können Sie jedes Framework betreiben, das WSGI unterstützt. Dies scheint der Hintergrund für die Einführung von WSGI zu sein.
・ Was ist dann uWSGI?
→ Es ist eine Art Anwendungsserver, der WSGI unterstützt. Sie können HTTP-Kommunikation und UNIX-Domain-Socket-Kommunikationsmethoden verwenden, aber ich lasse dies, da es nicht geholfen werden kann, wenn ich jetzt tiefer gehe.
・ Was sind Webserver und Anwendungsserver überhaupt?
→ Der Webserver dient zum Ausführen einer Verarbeitung nach Erhalt einer Anforderung vom Benutzer. Mit anderen Worten, es sei denn, Sie befinden sich in einer lokalen Umgebung. Das Bild lautet, dass die gesendete Anforderung im Wesentlichen zuerst an den Webserver gesendet wird und entscheidet, was damit geschehen soll. Mit Ausnahme dynamischer Anfragen (Anfragen nach CSS, Javascript, Bildern, Videos usw., die sich häufig ändern können) kann hier die Verarbeitung erfolgen. Wenn umgekehrt diese Anforderungen eingehen, kann gesagt werden, dass sie die Aufgabe haben, die Anforderungen an den Anwendungsserver weiterzuleiten. Wenn Sie in CSS und Bildern statisch sind, können Sie diese natürlich hier verarbeiten.
Was ist ein Anwendungsserver? Kurz gesagt, es ist derjenige, auf dem die Anwendung ausgeführt wird. Anfragen und Antworten werden dort weitergeleitet, wo es leicht zu verstehen ist. Am Beispiel des Anmeldevorgangs
Es stellt sich heraus, dass. Ich hatte das Gefühl, dass auch nur ein Login ein ziemlich komplizierter Prozess ist.
docker-compose.yml
version: '3.7'
volumes:
django.db.volume:
name: django.db.volume
services:
nginx:
image: nginx:1.13
container_name: app_nginx
ports:
- "8000:8000"
volumes:
- ./nginx/conf:/etc/nginx/conf.d
- ./nginx/uwsgi_params:/etc/nginx/uwsgi_params
- ./static:/static
- ./nginx/log:/var/log/nginx
depends_on:
- python
db:
tty: true
image: mariadb:10.1
container_name: app_mariadb
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
TZ: 'Asia/Tokyo'
volumes:
- django.db.volume:/var/lib/mariadb
- ./db/sql:/docker-entrypoint-initdb.d
python:
build: ./python
image: python_blog
container_name: app_python
command: uwsgi --ini /code/project/uwsgi.ini
environment:
- DATABASE_HOST=db
volumes:
- ./src:/code
- ./static:/static
- ./python:/code/python
expose:
- "8888"
depends_on:
- db
Zusammenfassend ist die Pfadangabe in Volumes "Host-Seite: Seite der virtuellen Umgebung" und "tty: true" eine Beschreibung, die den Container auf dem Laufenden hält. Dieses Mal war ich süchtig nach dem Sumpf, weil ich mit Docker unter Windows zu tun hatte oder weil ich aufgrund des Komforts des Docker-Containersystems große Schwierigkeiten hatte, den Verbindungsfehler zur Datenbank zu beseitigen. Als Ergebnis der Untersuchung wurden beide als Grund angeführt, aber ich denke, dass der Grund für letzteres darin besteht, dass ich die Änderungen reflektiert und Docker mit down beendet habe. Dieses Mal sollte das DB-Volume in Docker gespeichert werden, indem ein Verzeichnis zum Speichern und Freigeben von DB-Informationen auf der Hostseite vorbereitet wird. Um das Volume am Anfang zu mounten, habe ich es zunächst gelöst, indem ich es nur für die Persistenz des Mariadb-Containers erstellt habe. Django.db.volume existiert übrigens nicht im Verzeichnis auf der Windows-Seite? Im Fall der Docker Toolbox ist dies jedoch sehr kompliziert
Windows ⇒ Virtual Box ⇒ Docker == Haupthost ⇒ Host von Docker aus gesehen (Gast bei Betrachtung von Windows) ⇒ Gast
Da sich das diesmal erstellte Volume in der virtuellen Box befindet, wird es unter Windows nicht angezeigt, was verwirrend ist. Einer der Vorteile von Docker besteht darin, dass Sie problemlos Container erstellen und löschen können. Wenn Sie jedoch Daten wie DB nicht beibehalten, führt dies zu einem Verbindungsfehler. Stellen Sie daher sicher, dass dies ein Mittel zur Beständigkeit ist. Lass es uns nehmen. Übrigens, wenn Sie dokcer-compose.yml verwenden, sollten Sie wahrscheinlich verschiedene Änderungen und Aktualisierungen vornehmen, indem Sie damit anstelle der Docker-Datei spielen. Denken Sie jedoch in diesem Fall daran, dass der Build in up reflektiert werden kann, ohne dass dies erforderlich ist. Es war. Im Fall von Dockerfile ist ein Build erforderlich. Wenn Sie also die Datenbank nicht dauerhaft machen, wird wahrscheinlich ein Fehler angezeigt (aufgetreten).
Schreiben Sie für nginx die Einstellungen in die conf-Datei und bereiten Sie eine Parameterdatei für uWSGI vor.
app_nginx.conf
upstream django {
ip_hash;
server python:8888;
}
# configuration of the server(Serverkonfiguration)
server {
# the port your site will be served on
listen 8000;
# the domain name it will serve for
server_name 127.0.0.1; # substitute your machine`s IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M;
location /static {
alias /static;
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /etc/nginx/uwsgi_params; # the uwsgi_params file you installed
}
}
Der Zugriff wird zuerst an Port 8000 empfangen. Wenn es sich um eine Anforderung an eine statische Datei handelt, übergeben Sie sie an static von nginx. Wenn Sie die Anforderung an einen anderen Anwendungsserver (uWSGI) übergeben müssen, überspringen Sie die Anforderung an Port 8888. Vergessen Sie nicht, das Verzeichnis anzugeben, in dem sich die uWSGI-Parameterdatei am Ende befindet.
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
Es ist ein sogenannter Zauber.
Wenn Sie während der Entwicklung zusätzliche Pakete installieren möchten, können Sie direkt in den Container gehen und "python -m pip install" ausführen. Da ich jedoch "require.txt" erstellt habe, werde ich dies verwenden Ich will.
Wenn jedoch nichts unternommen wird, tritt ein Fehler auf, selbst wenn Sie beispielsweise "python -m pip install require.txt" verwenden.
Haben Sie in DockerFile COPY
und ADD
gemacht? Ich hatte eine Frage und beschloss, sie vorerst zu überprüfen.
# docker exec -it app_Finden Sie aus Python Bash./Ergebnis der Befehlsausführung
./
./project
./project/app
./project/app/admin.py
./project/app/apps.py
./project/app/migrations
./project/app/migrations/0001_initial.py
./project/app/migrations/0002_sampledb.py
./project/app/migrations/__init__.py
./project/app/migrations/__pycache__
./project/app/migrations/__pycache__/0001_initial.cpython-38.pyc
./project/app/migrations/__pycache__/0002_sampledb.cpython-38.pyc
./project/app/migrations/__pycache__/__init__.cpython-38.pyc
./project/app/models.py
./project/app/tests.py
./project/app/urls.py
./project/app/views.py
./project/app/__init__.py
./project/app/__pycache__
./project/app/__pycache__/admin.cpython-38.pyc
./project/app/__pycache__/apps.cpython-38.pyc
./project/app/__pycache__/models.cpython-38.pyc
./project/app/__pycache__/urls.cpython-38.pyc
./project/app/__pycache__/views.cpython-38.pyc
./project/app/__pycache__/__init__.cpython-38.pyc
./project/manage.py
./project/media
./project/polls
./project/polls/admin.py
./project/polls/apps.py
./project/polls/migrations
./project/polls/migrations/0001_initial.py
./project/polls/migrations/0002_auto_20200408_1848.py
./project/polls/migrations/__init__.py
./project/polls/migrations/__pycache__
./project/polls/migrations/__pycache__/0001_initial.cpython-38.pyc
./project/polls/migrations/__pycache__/0002_auto_20200408_1848.cpython-38.pyc
./project/polls/migrations/__pycache__/__init__.cpython-38.pyc
./project/polls/models.py
./project/polls/tests.py
./project/polls/urls.py
./project/polls/views.py
./project/polls/__init__.py
./project/polls/__pycache__
./project/polls/__pycache__/admin.cpython-38.pyc
./project/polls/__pycache__/apps.cpython-38.pyc
./project/polls/__pycache__/models.cpython-38.pyc
./project/polls/__pycache__/tests.cpython-38.pyc
./project/polls/__pycache__/urls.cpython-38.pyc
./project/polls/__pycache__/views.cpython-38.pyc
./project/polls/__pycache__/__init__.cpython-38.pyc
./project/project
./project/project/settings.py
./project/project/urls.py
./project/project/uwsgi.log
./project/project/views.py
./project/project/wsgi.py
./project/project/__init__.py
./project/project/__pycache__
./project/project/__pycache__/settings.cpython-38.pyc
./project/project/__pycache__/urls.cpython-38.pyc
./project/project/__pycache__/views.cpython-38.pyc
./project/project/__pycache__/wsgi.cpython-38.pyc
./project/project/__pycache__/__init__.cpython-38.pyc
./project/templates
./project/templates/admin
./project/templates/admin/base_site.html
./project/templates/admin/index.html
./project/templates/app_folder
./project/templates/app_folder/page01.html
./project/templates/app_folder/page02.html
./project/templates/app_folder/top_page.html
./project/templates/base.html
./project/templates/polls
./project/templates/polls/detail.html
./project/templates/polls/index.html
./project/templates/polls/results.html
./project/uwsgi.ini
Der Befehl "find. /" Ist ein Linux-Befehl, der "Verzeichnisse suchen und anzeigen unter dem Stammordner" bedeutet.
Einige Dateien für die Django-Tutorials nach diesem Artikel sind ebenfalls gemischt. Wenn Sie sie jedoch sorgfältig prüfen, können Sie feststellen, dass require.txt
fehlt.
In DockerFile ist es "COPY ./requirements.txt / code" und es ist ein Container, der basierend auf diesem Image erstellt wurde, aber ich verstehe nicht warum.
Ich denke jedoch daran, dass mein Verständnis des Befehls "Docker-Compose Run" zu vielfältig und zu vielfältig war, was zu einer unendlichen Anzahl von Containern führte ...
Wenn jemand weiß, lassen Sie es mich bitte wissen.
Jetzt besteht die Lösung vorerst darin, "require.txt" auf dem Container zu mounten.
Also habe ich die Beschreibung von ./python: / code / python
zu docker-compose.yml
hinzugefügt.
Auf diese Weise können Sie "up" ausführen und mit dem Befehl "docker exec" eingeben und "pip install -r. / Python / require.txt" ausführen, um zusätzliche Pakete zu installieren.
Wenn Sie fertig sind, erstellen Sie einen Container mit "docker-compose up -d --build". Zusammenfassend lässt sich sagen, dass die Option -d den Container im Hintergrund laufen lässt.
Es ist in Ordnung, es zu tun, aber wenn Sie es so starten, wie es ist, wird es nicht wirklich gut starten.
Der Grund ist, dass uWSGI noch nicht fertig ist.
Wenn Sie sich noch einmal docker-comopose.yml
ansehen, werden Sie feststellen, dass die Container nginx und python eine Abhängigkeitsspezifikation haben.
Wir haben zuvor erfahren, dass dies ein Hinweis auf Containerabhängigkeiten ist.
Mit anderen Worten, die Nginx- und Python-Container können nur gestartet werden, wenn der DB-Container gestartet wird.
Der wesentliche Datenbankserver funktioniert jedoch nicht ohne den Anwendungsserver, sodass uWSGI jetzt nicht bereit ist und der Container nicht gestartet wird ... Dies geschieht.
Erstellen Sie also zuerst ein Django-Projekt und eine uwsgi-Konfigurationsdatei.
docker-compose run --rm python django-admin.py startproject project
Der Befehl run ** erstellt einen neuen Container ** und führt den angegebenen Befehl aus. Also ** Wenn Sie es oft benutzen, haben Sie unendlich viele Container **. Verwenden Sie daher unbedingt den Befehl "--rm", es sei denn, Sie haben eine bestimmte Absicht.
Übrigens gibt es auch einen Befehl namens "docker-compose exec $ {service_name} $ {command}", der den Befehl im laufenden Container ausführt.
Wenn Sie beispielsweise "docker-compose exec python bash" ausführen, können Sie den Container des Python-Dienstes eingeben und dort den Befehl bash ausführen.
Geben Sie nun nach dem Ausführen den von Ihnen festgelegten Dienstnamen und den Zauber an, der das Django-Projekt generiert.
Anschließend wird in dem von WORKDIR angegebenen Bereich ein Ordner mit dem nach "Projekt starten" angegebenen Namen erstellt.
Und schließlich wird der Container mit dem Befehl --rm
gelöscht.
Da das Ergebnis von "django-admin.py startproject project" jedoch auf der Hostseite verbleibt, kann es sich beim anschließenden Start des Containers widerspiegeln, sodass kein Problem besteht.
uwsgi.ini
[uwsgi]
socket = :8888
module = project.wsgi
wsgi-file = /code/project/project/wsgi.py
logto = /code/project/project/uwsgi.log
chdir=/code/project
py-autoreload = 1
Erstellen Sie anschließend eine Einstellungsdatei wie oben beschrieben und legen Sie sie im selben Verzeichnis wie "manage.py" der erstellten Projektdatei ab. Was geschrieben wird, ist der von uWSGI verwendete Port, die Protokolldatei und der Speicherort der wsgi-Datei. Beachten Sie außerdem, dass Django-Projekte immer Verzeichnisse angeben und Befehle ausführen, die auf "manage.py" basieren.
Wenn du so weit bist
$ docker-compose up -d
$ docker ps -a
Und den Zauber wirken. Der letzte Spruch kann eine Liste von Containern anzeigen. Stellen Sie daher sicher, dass 3 Container aktiv sind und alle aktiv sind. Wie eingangs erwähnt, kommt es bei der Verwendung von MySQL mit Docker manchmal vor, dass es nicht hier oben wird, sondern sofort beendet wird. Dieses Mal denke ich, dass es kein Problem gibt, weil ich Maßnahmen ergriffen habe, die bisher durchgeführt werden können, aber ich persönlich dachte, dass es besser ist, zuerst die folgende Tabelle vorzubereiten, bevor Sie den Zauber hier wirken. ..
sql:./db/sql/init.sql
DATENBANK ERSTELLEN, WENN NICHT VORHANDEN Beliebiger Datenbankname CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER IF NOT EXISTS 'Beliebiger Benutzername'@'%' IDENTIFIED BY 'password';
Der auf GRANT ALL PRIVILEGES ON angegebene Datenbankname.* TO 'Der oben angegebene Datenbankname'@'%';
FLUSH PRIVILEGES; #werde nicht vergessen
Es ist ein Zauber mit dem bekannten SQL-Stil.
MySQL erstellt immer eine Datenbank und einen Benutzer. Wenn Sie dem erstellten Benutzer nicht zuerst die vollen Rechte für diese Datenbank erteilen (dies kann auch in Tabelleneinheiten angegeben werden), sind Sie schlecht gelaunt. Stellen Sie dies also zuerst ein Ich werde das machen.
Der Benutzername und das Passwort in der zweiten Zeile können übrigens auch in "docker-compose.yml" festgelegt werden.
Dieses Mal wird das Root-Passwort von MySQL im Teil MYSQL_ROOT_PASSWORD: root
festgelegt.
Dieses Mal geben wir allen Datenbanken die vollen Rechte, also legen Sie den Root-Benutzer fest.
Übrigens werden der Benutzername und das Kennwort als root festgelegt, aber dies ist natürlich zulässig, da es lokal ist und in der Produktionsumgebung für die Sicherheit zu unangenehm ist. Lassen Sie es uns also richtig festlegen.
Wie Sie bisher beim Schreiben sehen können, handelt es sich hierbei um eine SQL-Initialisierungsdatei.
Nachdem Sie so weit gekommen sind, werfen wir einen Blick auf die Django-Konfigurationsdatei.
project/project/settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_test',
'USER': 'root',
'PASSWORD': 'root',
'HOST': 'db',
'PORT': '3306',
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
'charset': 'utf8mb4',
},
}
}
#Unterlassung
STATIC_ROOT = '/static'
STATIC_URL = '/static/'
Sie können fast verstehen, was geschrieben steht.
Es scheint, dass der ENGINE-Teil je nach Version von Django unterschiedlich sein kann, aber in diesem Fall schreiben Sie ihn bitte in einen geeigneten um.
Legen Sie danach den Datenbanknamen und die Elemente fest, die sich auf den Root-Benutzer beziehen.
Legen Sie für den HOST-Teil den Dienstnamen des Containers fest, der die in "docker-compose.yml" angegebene Datenbank enthält, und legen Sie für PORT auch den dort angegebenen Port fest.
OPTION ist ein Zauber.
'init_command':" SET sql_mode = 'STRICT_TRANS_TABLES' "
Es wird empfohlen, dies hier anzugeben, also setzen wir es.
Es scheint ein Modus zu sein, der viele Datenintegritätsprobleme in MySQL löst.
Übrigens habe ich einen Fehler bekommen, wenn ich ihn nicht eingestellt habe.
Der letzte Teil ist die Verzeichniseinstellung für statische Dateien, andernfalls wird die statische Datei nicht geladen.
Wenn du so weit bist
Geben Sie den Container mit "docker exec -it app_python bash" ein
cd ./project/
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
Lass uns den Zauber wirken. Wenn die Migration erfolgreich abgeschlossen wurde, ohne hier einen Fehler auszulösen, bedeutet dies, dass der Datenbankzugriff erfolgreich war. Erstellen wir also einen Container mit up -d früher.
Danach werden wir Django gründen. Erstellen Sie zuvor zunächst einen Anwendungsordner im Projekt
Geben Sie den Container mit "docker exec -it app_python bash" ein
cd ./project/
python manage.py startapp Ordnername
Stellen Sie nach der Ausführung settings.py
wie folgt ein.
project/project/settings.py
"""
Django settings for project project.
Generated by 'django-admin startproject' using Django 2.1.5.
For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '&$l0ho%f&-w%&t_2l=@98u(i_58t15d-jn+ln5fuyvy(^l88^t'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app.apps.AppConfig', #hinzufügen
'bootstrap4' #hinzufügen
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware', #hinzufügen
]
ROOT_URLCONF = 'project.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')], #Geben Sie das Verzeichnis des Ordners an, der die HTML-Vorlage enthält
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
'builtins':[
'bootstrap4.templatetags.bootstrap4',#Hier hinzufügen!
],
},
},
]
WSGI_APPLICATION = 'project.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_test',
'USER': 'root',
'PASSWORD': 'root',
'HOST': 'db',
'PORT': '3306',
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
'charset': 'utf8mb4',
},
}
}
# Password validation
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = '/static'
# Custom User
AUTH_USER_MODEL = 'app.User'
#Einstellungen für Mediendateien
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
Beim Auszug
'app.apps.AppConfig', #hinzufügen
'bootstrap4' #hinzufügen
apps.py
from django.apps import AppConfig
class AppConfig(AppConfig):
name = 'app'
Dieser Teil gibt den Speicherort von apps.py
oben an.
Wie Sie sehen können, importiert apps.py
das AppConfig
-Objekt des django.apps
-Moduls.
Vergessen Sie nicht, "name =" Anwendungsordnername "festzulegen, in dem Sie die folgende Klasse erstellt haben.
Übrigens, wenn Sie nach dem Erstellen eines Anwendungsordners nicht "app.apps.AppConfig" hinzufügen, wird eine Fehlermeldung angezeigt (Erfahrungsgeschichte).
Der untere Teil ist die Einstellung für die Verwendung von Bootstrap mit Django. Fügen Sie diese ebenfalls hinzu.
'builtins':[
'bootstrap4.templatetags.bootstrap4',#Hier hinzufügen!
],
Dies ist auch eine Spezifikation für die Verwendung von Bootstrap. Vergessen Sie also nicht, sie hinzuzufügen.
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
Geben Sie die Zeitzone und die Djnago-Einstellungssprache an.
# Custom User
AUTH_USER_MODEL = 'app.User'
Dies ist eine Einstellung, die der benutzerdefinierte Benutzer später erstellen soll.
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
Es wird zur Zugriffseinstellung der Mediendatei. Es wird bei der Implementierung der Upload-Funktion und der Funktion zum Anzeigen der hochgeladenen Datei als Inhalt auf dem Bildschirm in der Anwendung verwendet. Damit sind die grundlegenden Vorbereitungen für die Verwendung von Django abgeschlossen.
Von hier aus erstellen wir eine Vorlage. Da Django ein Framework ist, besteht es aus MVC-Modellen wie Laravel. Dies wird in Django als MVT-Modell bezeichnet.
Mit anderen Worten, es ist ein "Model / Tenmplaete / View-Modell". Als Rolle
Modell: Datenbanksteuerung Vorlage: Steuern Sie den Bildschirm. Die Rolle von View im MVC-Modell Ansicht: Die Rolle der Gesamtsteuerung. Rolle des Controllers im MVC-Modell
Es wird sein. Beachten Sie, dass die Ansicht im MVC-Modell und die Ansicht im MTV-Modell unterschiedliche Rollen haben. Daher kann die Vorlage in Django verwendet werden, daher werden wir sie festlegen.
template/base.html
<!DOCTYPE html>
{% load bootstrap4 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='slim' %}
{% load static %}
<html lang="ja">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type='text/css' href="{% static 'css/style.css' %}">
<link rel="stylesheet" href="https://cccabinet.jpn.org/bootstrap4/css/style.css">
<title>Django Entwicklungsbeispiel</title>
{% block extra_css %}{% endblock %}
</head>
<body>
<!-- navbar -->
<div class="container">
<div class="row">
<div class="col-12">
<nav class="navbar navbar-expand-lg fixed-top navbar-dark bs-navbar" style="background-color:cadetblue;" id='bs-navbar'>
<a class="navbar-brand mr-md-2" href="/app/top_page">
Beispiel für einen Entwicklungsbildschirm
</a>
<!-- layout_dammy -->
<ul class="navbar-nav mr-auto">
<li class="nav-item"><a class='nav-link' href="#"></a></li>
<li class="nav-item"><a class='nav-link' href="#"></a></li>
</ul>
<!-- layout -->
<ul class="navbar-nav">
<li class="nav-item"><a class="nav-link" href="/#">Probe 1</a></li>
<li class="nav-item"><a class="nav-link" href="/#">Probe 2</a></li>
<li class="nav-item"><a class="nav-link" href="/#">Probe 3</a></li>
<li class="nav-item"><a class="nav-link" href="/accounts/login">Einloggen</a></li>
<li class="nav-item"><a class="nav-link" href="/accounts/logout">Ausloggen</a></li>
</ul>
</nav>
</div><!-- /.col-12 -->
</div><!-- /.row -->
</div>
<!-- sidebar&main-contents -->
<div class="container-fluid" id="content">
<div class="row flex-xl-nowrap">
<!-- sidebar -->
<div id="sidemenu" class="col-2 d-none d-md-block bg-light sidebar align-self-start">
<div class="sidebar-sticky">
<ul class='nav flex-column'>
<li class="nav-item">
<nav class="navbar navbar-light bg-light">
<a class="navbar-brand" href="/#">
<span data-feather=""></span>Oberste Seite
</a>
</nav>
</li>
<li class="nav-item">
<nav class="navbar navbar-light bg-light">
<a class="navbar-brand" href="/#">
<span data-feather=""></span>Seitenleiste 1
</a>
</nav>
</li>
<li class="nav-item">
<nav class="navbar navbar-light bg-light">
<a class="navbar-brand" href="/#">
<span data-feather=""></span>Seitenleiste 2
</a>
</nav>
</li>
<li class="nav-item">
<nav class="navbar navbar-light bg-light">
<a class="navbar-brand" href="/#">
<span data-feather=""></span>Seitenleiste 3
</a>
</nav>
</li>
<li class="nav-item">
<nav class="navbar navbar-light bg-light">
<a class="navbar-brand" href="/#">
<span data-feather=""></span>Seitenleiste 4
</a>
</nav>
</li>
<li class="nav-item">
<nav class="navbar navbar-light bg-light">
<a class="navbar-brand" href="/#">
<span data-feather=""></span>Seitenleiste 5
</a>
</nav>
</li>
</ul>
</div><!-- /.sidebar-sticky -->
</div><!-- /#sidemenu -->
<div class="col-10">
{% block contents %}
{% endblock %}
</div><!-- /.col-10 -->
</div><!-- /.row -->
</div><!-- /#content -->
</body>
</html>
<!-- sidebar-icon -->
<!-- use-icon: https://voyager-jp.com/blog/javascript/feather/ -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/feather-icons/4.9.0/feather.min.js"></script>
<script>feather.replace()</script>
Erstellen Sie zunächst eine Vorlage für das Teil, das jeder Seite gemeinsam ist. Es ist eine Kopfzeile oder eine Navigationsleiste. Notationen wie "{%%}" sind Zaubersprüche, die in Vorlagen verwendet werden. Hier einige Auszüge
{% load bootstrap4 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='slim' %}
{% load static %}
Lädt das Bootstrap-Modul, jQuery und statische Dateien. Wenn Sie es nicht angeben, wird der Bootstrap nicht angewendet. Vergessen Sie es also nicht. Wenn es einen Zauber wie diesen gibt
<link rel="stylesheet" type='text/css' href="{% static 'css/style.css'%}">
Sie können es auch verwenden, um die Pfadangabe zu vereinfachen. Apropos
{% block %}
{% endblock %}
Das ist die Bezeichnung des Gebiets. Zum Beispiel
{% block extra_css %}{% endblock %}
Dies bedeutet, dass "Block" in "Endblock" in "Block" mit dem Namen "extra_css" geändert wird. Der auf diese Weise angegebene Block wird zum Standardwert und bei Vererbung durch die unten stehende untergeordnete Vorlage
Der Bereich, in dem der Name "block" nicht angegeben ist, z. B. "{% block%} ~ {% endblock%}" oder "{% block extra_css%} {% endblock%}". Wird eingefügt.
Deshalb
{% block contents %}
{% endblock %}
Wenn Sie einen Zauber wie den oben genannten wirken, können Sie sehen, dass der Teil der untergeordneten Vorlage, der denselben Zauber wirkt, eingefügt wird.
Übrigens lade ich diesmal Bootstrap mit CDN, aber CDN hat verschiedene Probleme. Wenn möglich, möchte ich das Paket herunterladen und das lokal geladene Paket laden.
Danach werde ich eine untergeordnete Vorlage erstellen
templates/app_folder/top_page.html
{% extends 'base.html' %}
{% block contents %}
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center mt-5 border-bottom">
<h1 class="h2">oberste Seite</h1>
</div>
<div>
<h4>Beschreiben Sie den Inhalt hier</h4>
</div>
{% endblock %}
templates/app_folder/page01.html
{% extends 'base.html' %}
{% block contents %}
<h4 class="mt-5 mb-4 border-bottom">Geben Sie die Suchbedingungen ein</h4>
<form action="{% url 'app:top_page' %}" method="post">
<div class="container-fluid">
<div class="row">
<div class="col-2">
<input class="form-control" type="next" name="input_data" maxlength="255">
</div><!-- /.col-2 -->
<div class="col-2">
<div class="text-left align-bottom">
<button type="submit" name="button" class="btn btn-info">
Suche
</button>
</div><!-- /.text-left -->
</div><!-- /.col-2 -->
</div><!-- /.row -->
</div><!-- /.container-fluid -->
{% csrf_token %}
</form>
{% endblock %}
templates/app_folder/page02.html
{% extends 'base.html' %}
{% block contents %}
<h4 class="mt-5 mb-4 border-bottom">DB-Suchergebnisse anzeigen</h4>
<div class="container-fluid">
<div class="row">
<div class="col-4">
<p>sample1:{{result_sample1}}</p>
<p>sample2:{{result_sample2}}</p>
</div>
</div>
</div>
{% endblock %}
Der Zauber "{% erweitert'base.html"%} "erbt die vorherige übergeordnete Vorlage. Der Inhalt von Seite01 und Seite02
・ Empfangen Sie Suchbedingungen über das Eingabeformular auf dem Bildschirm
Dies bedeutet, dass Sie eine Benutzeroberfläche erstellt haben, um den Prozess auf dem Verwaltungsbildschirm auszuführen.
Nachdem die Vorlage fertig ist, legen Sie auch die Ansicht und das Modell fest.
Zitat aus dem Artikel des Planers, der im Referenzartikel aufgeführt ist
app_config / views.py: Grobe Kontrolle über das Ganze app_folder / views.py: Steuern Sie einzelne Funktionen
Beachten Sie, dass die gleiche views.py
wie, aber mit unterschiedlichen Rollen, was verwirrend ist.
Übrigens diesmal
app_config / views.py
ist project / project / views.py
(befindet sich im selben Verzeichnis wie settings.py).
Ersetzen Sie app_folder / views.py
durch project / app / views.py
.
project/project/views.py
from django.shortcuts import render, redirect, reverse
from django.views import View
class index(View):
def get(self, request, *args, **kwargs):
return redirect(reverse('app:top_page'))
index = index.as_view()
Wenn auf das System zugegriffen wird, wird es zur obersten Seite übersprungen.
project/app/views.py
from django.shortcuts import render
from django.views import View
from .models import SampleDB
class SampleView(View):
def get(self, request, *args, **kwargs):
return render(request, 'app_folder/page01.html')
def post(self, request, *args, **kwargs):
input_data = request.POST['input_data']
result = SampleDB.objects.filter(sample1=input_data)
result_sample1 = result[0].sample1
result_sample2 = result[0].sample2
context={'result_sample1':result_sample1, 'result_sample2':result_sample2}
return render(request, 'app_folder/page02.html', context=context,)
top_page = SampleView.as_view()
Achten Sie auf Tippfehler.
Machen Sie keinen Fehler, denn von und zu Beginn sind Zaubersprüche. Der letzte Teil besteht darin, die Tabellenobjekte aus dem Modell zu importieren.
def get(self, request, *args, **kwargs):
return render(request, 'app_folder/page01.html')
Die Rendermethode ist eine Methode, die ein HttpResponse-Objekt zurückgibt. Wenn Sie im Argument eine Anforderung festlegen und den Pfad des Bildschirms angeben, in dem Sie das Ergebnis im zweiten Argument zurückgeben möchten, wird das Ergebnis einschließlich der Informationen rund um die Sitzung dort zurückgegeben.
def post(self, request, *args, **kwargs):
input_data = request.POST['input_data']
result = SampleDB.objects.filter(sample1=input_data)
result_sample1 = result[0].sample1
result_sample2 = result[0].sample2
context={'result_sample1':result_sample1, 'result_sample2':result_sample2}
return render(request, 'app_folder/page02.html', context=context,)
Dies ist eine Methode zum Empfangen von POST-Anforderungen vom Eingabeformular.
In der Kontextvariablen besteht der Prozess darin, den an die Vorlage übergebenen "Variablennamen" dem "Variablenwert" zuzuordnen und ihn mit der Rendermethode an die Variable zu übergeben.
Sie werden es an app_folder / page02.html
zurückgeben.
Es ist genau richtig, also lassen Sie uns das Modell auch hier einstellen.
project/app/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
pass
class SampleDB(models.Model):
class Meta:
db_table = 'sample_table' # tablename
verbose_name_plural = 'sample_table' # Admintablename
sample1 = models.IntegerField('sample1', null=True, blank=True) #Variablen und Einstellungen zum Speichern von Nummern
sample2 = models.CharField('sample2', max_length=255, null=True, blank=True) #Variablen und Einstellungen zum Speichern von Zeichenketten
Jede Klasse ist jede Tabelle. Mit anderen Worten, wenn Sie so schreiben, werden die Benutzertabelle und SampleDB erstellt. Da die in der diesmal erstellten Vorlage verwendete Tabelle SampleDB ist, erstellen Sie eine Klasse, setzen Sie "models.Model" als Argument und schreiben Sie die Tabelleneinstellungen unter "Klasse Meta".
db_table = 'sample_table' # tablename
verbose_name_plural = 'sample_table' # Admintablename
Dieser Teil ist die Einstellung des Tabellennamens und des Tabellennamens, die auf dem Verwaltungsbildschirm angezeigt werden.
sample1 = models.IntegerField('sample1', null=True, blank=True) #Variablen und Einstellungen zum Speichern von Nummern
sample2 = models.CharField('sample2', max_length=255, null=True, blank=True) #Variablen und Einstellungen zum Speichern von Zeichenketten
Wenn Sie so schreiben, legen Sie die Daten in der Tabelle fest. Mit anderen Worten, diese Tabelle speichert ID- und Zeichenfolgendaten.
Legen Sie die URL fest, die für den Zugriff auf das System über den Webbildschirm erforderlich ist. Ist es eine Routing-Einstellung in Laravel?
Genau wie views.py
app_config / urls.py: Systemweites URL-Design app_folder / urls.py: URL-Design innerhalb einzelner Apps
Bitte beachten Sie, dass es den gleichen Dateinamen wie und eine andere Rolle hat. Übrigens diesmal
app_config / views.py
ist project / project / urls.py
(befindet sich im selben Verzeichnis wie settings.py).
Ersetzen Sie "app_folder / views.py" durch "project / app / urls.py".
project/app/urls.py
from django.urls import path
from . import views
# URL_setting
app_name = 'app'
urlpatterns = [
path('top_page/', views.top_page, name='top_page')
]
Schreiben Sie den Pfad jeder Seite in den Teil "URL-Muster". Dieses Mal wird nur die TOP-Seite erstellt (Seite 01 und Seite 02 sind ausgeschlossen, da es sich um Verwaltungsbildschirmvorlagen handelt), sodass nur eine vorhanden ist.
project/project/urls.py
"""project URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from . import views
urlpatterns = [
#URL für den Zugriff auf die Verwaltungssite
path('admin/', admin.site.urls),
#URL für den Zugriff auf die diesmal erstellte App "App"
path('app/', include('app.urls')),
#Wenn Sie keine URL angeben (App_config/views.Mit py "App" automatisch_(Bereits für den Zugriff auf "Ordner" eingestellt)
path('', views.index, name='index'),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Erstellen Sie abschließend einen Verwaltungsbildschirm. Weil Sie dafür einen Administrator erstellen müssen Geben Sie den Container mit "docker exec -it app_python bash" ein
cd ./project/
python manage.py createsuperuser
Und den Zauber wirken. Auf was setzen Sie Ihren Benutzernamen, Ihre E-Mail-Adresse und Ihr Passwort, wenn Sie nicht weiterkommen? Sie werden gefragt, bitte stellen Sie es willkürlich ein. Als nächstes folgt die Einstellung der Verwaltungssite.
project/app/admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User
from.models import SampleDB
admin.site.register(User, UserAdmin)
admin.site.register(SampleDB)
Die Verwaltungsseite ist
Normalerweise müssen Sie MySQL usw. lernen, um DB zu betreiben Obwohl Python (Django) voll ist, ist MySQL unmöglich. .. Lassen Sie uns die Datenbank auf dem Bildschirm von der Verwaltungsseite aus bedienen!
Stellen Sie es also wie oben beschrieben gemäß der zu verwendenden Tabelle ein.
Jetzt starten wir das System.
Migrieren Sie zuvor die Tabelle und wenden Sie CSS auf der Verwaltungssite an. Ich habe die Migration vor langer Zeit einmal durchgeführt, aber da ich eine neue SampleDB-Tabelle definiert habe, werde ich sie erneut durchführen. Das ist der Zauber. Geben Sie den Container mit "docker exec -it app_python bash" ein
cd ./project/
python manage.py migrate
Als nächstes folgt die Anwendung von CSS. Dies würde bei Verwendung von uWSGI erfolgen. Die Zauber sind wie folgt
python manage.py collectstatic
Endlich, wenn es sicher gemacht ist
python manage.py runserver
Es ist ein Systemstart. Wenn kein Fehler ausgegeben wird, ist der Start erfolgreich abgeschlossen. Danke für deine harte Arbeit. Wenn es nicht funktioniert, versuchen Sie es erneut mit docker-compose up -d oder sehen Sie die entsprechende Fehlermeldung.
Sie können sehen, wie es funktioniert, wenn Sie die Erfahrung gemacht haben, Laravel zu machen. Schließlich werde ich jedoch die integrierte Methode der Vorlage verwenden und zunächst den Zauber des Modellteils schreiben, und ich kann mich nicht erinnern, es sei denn, ich überprüfe ihn jedes Mal und wiederhole die Eingabe und Ausgabe stetig. Ich fühlte mich genauso wie bei der Erstellung eines Portfolios in. Da ich es dieses Mal wagen werde, mit dem Können von Laravel im Regal an dem Projekt teilzunehmen, werde ich Django und das Können des dazugehörigen Webwissens verstehen, damit ich auch nur einen kleinen Beitrag stehlen und den Plan stehlen kann. Ich hoffe es kann noch ein wenig angehoben werden. Schauen Sie sich zunächst das offizielle Tutorial von Django an.
Artikel, der die Systementwicklung mit Django (Python) _Introduction ermöglicht Erstellen Sie eine Django-Umgebung mit Docker-Compose (MariaDB + Nginx + uWSGI) Python3.6 + NGINX + MariaDB10 + uWSGI Django Environment Greedy Set mit Docker-Compose Unterschiede zwischen Webserver und Anwendungsserver bei der Rails-Entwicklung (Übersetzung) Einführung in uWSGI Über "uWSGI" und Anwendungsserver Ich werde den Unterschied zwischen dem Webserver und dem Anwendungsserver auf leicht verständliche Weise erklären Welche Rolle spielt der AP-Server? Lassen Sie uns den Unterschied zum Webserver verstehen.
Recommended Posts