Django: Difference between revisions
No edit summary |
No edit summary |
||
(39 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
Django Turoial zum Thema Login | |||
https://learndjango.com/tutorials/django-login-and-logout-tutorial | |||
Ein mini Tutorial fuer nen Apache2/Debian Django... | Ein mini Tutorial fuer nen Apache2/Debian Django... | ||
Django Version 3.2.19 | |||
Line 8: | Line 19: | ||
Gutes Intro: <nowiki>https://tecadmin.net/install-django-on-debian/</nowiki> | Gutes Intro: <nowiki>https://tecadmin.net/install-django-on-debian/</nowiki> | ||
Deutsches gutes Intro: https://tutorial.djangogirls.org/de/django_start_project/ | |||
== Django Serializer == | |||
[[Django Serializer]] | |||
== Standard Django Datenbank Tables == | |||
=== auh_user === | |||
CREATE TABLE IF NOT EXISTS "auth_user" | |||
( "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, | |||
"password" varchar(128) NOT NULL, | |||
"last_login" datetime NULL, | |||
"is_superuser" bool NOT NULL, | |||
"username" varchar(150) NOT NULL UNIQUE, | |||
"last_name" varchar(150) NOT NULL, | |||
"email" varchar(254) NOT NULL, | |||
"is_staff" bool NOT NULL, | |||
"is_active" bool NOT NULL, | |||
"date_joined" datetime NOT NULL, | |||
"first_name" varchar(150) NOT NULL); | |||
== Model Object Commands == | |||
{| class="wikitable" | |||
|+ | |||
! | |||
! | |||
|- | |||
|entrySortedList = entry.objects.order_by(entryField) | |||
|Liefert eine Liste aller Entry-Objekte zurueck, sortiert nach entryField | |||
|- | |||
|allEntries = entry.objects.all() | |||
|Liefert eine Liste aller Entryobjekte zurueck | |||
|- | |||
|entryCount = entry.objects.all().count() | |||
|Liefert einen integer mit der Anzahl der DB-Objekte zurueck | |||
|- | |||
|entryObj = entry.objects.get(pk=1) | |||
|Liefert das Object mit dem Primary Key 1 zurueck. Der Type des Objects ist die Klasse "entry" | |||
|- | |||
|cheese_blog = Blog.objects.get(name="Cheddar Talk") | |||
| | |||
|- | |||
|entry = entry.object.get_or_create(entryField1="field1", entryField2="field2") | |||
|Erstellt ein neues Object in der Table. Liefert ein Objekt zurueck... | |||
|- | |||
|entry = entry.object.get_or_create(entryField1="field1", entryField2="field2")[0] | |||
|Erstellt ein neues Object in der Table. Liefert entryField1 zurueck... | |||
|- | |||
|wanted = Entry.objects.filter(pub_date__year=2006) | |||
|get all objects, select speciic, and pass the wanted ones | |||
|- | |||
|<code>SomeModel.objects.filter(id=id).delete()</code> | |||
|Loeschen eines DB-Objekts | |||
|- | |||
|b5.save() | |||
|save obj to db | |||
|} | |||
== Model Fields == | |||
{| class="wikitable" | |||
|+ | |||
!Name | |||
!Beispiele | |||
!Beschreibung Feld | |||
!Beschreibung Parameter | |||
|- | |||
|AutoField | |||
| | |||
| | |||
| | |||
|- | |||
|DateField | |||
|DateField(initial=datetime.date.today) | |||
DateField(default=date.today) | |||
| | |||
| | |||
|- | |||
|CharField | |||
| | |||
| | |||
| | |||
|- | |||
|DecimalField | |||
| | |||
| | |||
| | |||
|- | |||
|ForeignKey | |||
|models.ForeignKey(Blog, on_delete=models.CASCADE) | |||
| | |||
| | |||
|- | |||
|EmailField | |||
| | |||
| | |||
| | |||
|- | |||
|ImageField | |||
|models.ImageField(upload_to="/images/uploads", blank=True) | |||
| | |||
|Blank heisst, dass dieses Feld nicht vom user ausgefuellt werden muss. | |||
|- | |||
|IntegerField | |||
|models.IntegerField(default=0) | |||
| | |||
| | |||
|- | |||
|ManyToManyField | |||
|models.ManyToManyField(Author) | |||
| | |||
| | |||
|- | |||
|OneToOneField | |||
|DjangoUser = models.OneToOneField(User, on_delete=models.CASCADE,) | |||
| | |||
|CASCADE = Loesch das Onject, wenn Parent stirbt | |||
RESTRICT = Loesche nur die Verbindung zu dem toten Parent | |||
PROTECT = | |||
|- | |||
|TextField | |||
| | |||
| | |||
| | |||
|- | |||
|URLField | |||
|models.URLField(blank=True) | |||
| | |||
| | |||
|} | |||
=== Model Attribute === | |||
{| class="wikitable" | |||
|+ | |||
! | |||
! | |||
! | |||
! | |||
! | |||
|- | |||
|unique | |||
|Boolean | |||
|Darf der Datensatz schon in der DB-Table sein? | |||
| | |||
| | |||
|- | |||
|editable | |||
|Boolean | |||
|False heisst, es wird nicht im Django-Admin angezeigt. | |||
| | |||
| | |||
|} | |||
== Form Fields == | |||
externe Doku: | |||
https://docs.djangoproject.com/en/5.0/ref/forms/fields/ | |||
{| class="wikitable" | |||
|+ | |||
! | |||
! | |||
! | |||
! | |||
|- | |||
|forms.BooleanField(required=False) | |||
| | |||
| | |||
| | |||
|- | |||
|forms.DateField(initial=datetime.date.today) | |||
| | |||
| | |||
| | |||
|- | |||
|forms.CharField(required=False) | |||
| | |||
| | |||
| | |||
|- | |||
|forms.CharField(widget=forms.TextArea, label="Your name", max_length=100) | |||
| | |||
| | |||
| | |||
|- | |||
|forms.CharField(label="Your name", max_length=100) | |||
| | |||
| | |||
| | |||
|- | |||
|forms.EmailField() | |||
| | |||
| | |||
| | |||
|- | |||
|<code>forms.SubmitButtonField(label="", initial=u"Your submit button text")</code> | |||
| | |||
| | |||
| | |||
|} | |||
=== Form Attribute === | |||
{| class="wikitable" | |||
|+ | |||
! | |||
! | |||
! | |||
! | |||
! | |||
|- | |||
|required | |||
|boolean | |||
|Muss das Feld gefuellt sein? | |||
| | |||
| | |||
|- | |||
|widget=forms.HiddenInput | |||
| | |||
|wird benutzt um in CharFields den bots ne falle zu stellen | |||
| | |||
| | |||
|- | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|} | |||
== Template Commands == | |||
=== IF === | |||
{% if VARIABLE %} | |||
<nowiki><h1>Hallo {{ VARIABLE }}</nowiki><nowiki></h1></nowiki> | |||
{% else %} | |||
<nowiki><h1>Hallo Welt</h1></nowiki> | |||
{% endif %} | |||
=== Embed HTML sourcefiles === | |||
<code>{% extends "sourcefile.html" %}</code> | |||
{% include 'sourcefile.html' %} | |||
=== Block === | |||
{% block block_beispiel_name %} | |||
{% endblock %} | |||
...endblock oder {% endblock block_beispiel_name %} funktionieren beide | |||
== Views.py Commands == | |||
=== Variables === | |||
x = 1 | |||
== Python Config == | == Python Config == | ||
Line 21: | Line 313: | ||
source ~/<mark>myproject</mark>/<mark>myprojectenv</mark>/bin/activate | source ~/<mark>myproject</mark>/<mark>myprojectenv</mark>/bin/activate | ||
== Django Config Dateien == | |||
Projekt - urls.py | |||
{| class="wikitable" | |||
|+ | |||
!Directory | |||
!Dateiname | |||
!Beschreibung | |||
|- | |||
|Projekt | |||
|urls.py | |||
| | |||
|- | |||
|Application | |||
|urls.py | |||
| | |||
|- | |||
|Application | |||
|views.py | |||
| | |||
|} | |||
Line 75: | Line 389: | ||
=== Configure Static Files === | === Configure Static Files === | ||
{{Code|vi django_app/settings.py}} | |||
vi django_app/settings.py | |||
Fuege 2 Zeilen hinzu... | Fuege 2 Zeilen hinzu... | ||
Line 89: | Line 402: | ||
python manage.py startapp MyApp | python manage.py startapp MyApp | ||
cd MyApp | |||
vi urls.py | |||
from django.urls import path | |||
from django.urls import path | |||
from . import views | |||
urlpatterns = [ | |||
path("", views.index, name="index"), | |||
] | |||
Die folgende Datei ist zustaendig fuer die Projekt URLs. Hier soll nur ein include passieren, damit die URLs in der App gemanaged werden. | |||
cd MyProject | |||
vi urls.py | |||
urlpatterns = [ | |||
path("MyApp/", include("MyApp.urls")), | |||
path('admin/', admin.site.urls), | |||
] | |||
cd MyApp | |||
vi view.py | |||
from django.shortcuts import render | |||
from django.http import HttpResponse | |||
def index(request): | |||
return HttpResponse("Halli Hallo Schwestern") | |||
== Django Errors == | |||
=== attempt to write a readonly database === | |||
Problem: | |||
* Aufrufe der Seite die die Datenbank benutzen, wirft den Fehler "attempt to write a readonly database" | |||
Lösung: | |||
* die Datenbankdatei muss 664 als Rechtemaske haben | |||
* das Verzeichnis muss dem Apache User und der Apache Gruppe gehören | |||
* Die Datenbankdatei muss dem Apache User und der Apache Gruppe gehören | |||
=== URL Redirecting not working === | |||
=== DisallowedHost - Invalid HTTP_HOST header === | |||
Problem: | |||
Er wollte einfach nicht die IP erlauben | |||
Loesung: | |||
Es war ein tippfehler in der Allowed_Host Variable der Settings | |||
=== ModuleNotFoundError: No module named 'MyProject' === | |||
Problem: | |||
Der Apache schmeisst einen 500 Internal Server Error. Die Logs sagen: | |||
ModuleNotFoundError: No module named 'MyProject' | |||
Failed to exec Python script file '/PATH/MyProject/wsgi.py'. | |||
mod_wsgi (pid=4996): Exception occurred processing WSGI script '/PATH/MyProject/wsgi.py'. | |||
Traceback (most recent call last): | |||
File "/PATH/MyProject/wsgi.py", line 16, in <module> | |||
application = get_wsgi_application() | |||
File "/PATH/site-packages/django/core/wsgi.py", line 12, in get_wsgi_application | |||
django.setup(set_prefix=False) | |||
File "/PATH/site-packages/django/__init__.py", line 19, in setup | |||
configure_logging(settings.LOGGING_CONFIG, settings.LOGGING) | |||
File "/PATH/site-packages/django/conf/__init__.py", line 82, in __getattr__ | |||
self._setup(name) | |||
File "/PATH/django/conf/__init__.py", line 69, in _setup | |||
self._wrapped = Settings(settings_module) | |||
File "/PATH/site-packages/django/conf/__init__.py", line 170, in __init__ | |||
mod = importlib.import_module(self.SETTINGS_MODULE) | |||
File "/usr/lib/python3.7/importlib/__init__.py", line 127, in import_module | |||
return _bootstrap._gcd_import(name[level:], package, level) | |||
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import | |||
File "<frozen importlib._bootstrap>", line 983, in _find_and_load | |||
File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked | |||
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed | |||
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import | |||
File "<frozen importlib._bootstrap>", line 983, in _find_and_load | |||
File "<frozen importlib._bootstrap>", line 965, in _find_and_load_unlocked | |||
ModuleNotFoundError: No module named 'MyProject' | |||
Loesung: | |||
In der wsgi.py nen import und nen Pfad hinzufuegen... | |||
import sys | |||
sys.path.append('/PATH/MyProject') | |||
=== ModuleNotFoundError: No module named 'importlib_metadata' === | |||
Loesung | |||
Manuelles nachinstallieren der Lib... pip3 install importlib_metadata |
Latest revision as of 15:55, 1 January 2024
Django Turoial zum Thema Login
https://learndjango.com/tutorials/django-login-and-logout-tutorial
Ein mini Tutorial fuer nen Apache2/Debian Django...
Django Version 3.2.19
Udemy Course: Python and Django Full Stack Web Developer Bootcamp
Gutes Intro: https://tecadmin.net/install-django-on-debian/
Deutsches gutes Intro: https://tutorial.djangogirls.org/de/django_start_project/
Django Serializer
Standard Django Datenbank Tables
auh_user
CREATE TABLE IF NOT EXISTS "auth_user"
( "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"password" varchar(128) NOT NULL,
"last_login" datetime NULL,
"is_superuser" bool NOT NULL,
"username" varchar(150) NOT NULL UNIQUE,
"last_name" varchar(150) NOT NULL,
"email" varchar(254) NOT NULL,
"is_staff" bool NOT NULL,
"is_active" bool NOT NULL,
"date_joined" datetime NOT NULL,
"first_name" varchar(150) NOT NULL);
Model Object Commands
entrySortedList = entry.objects.order_by(entryField) | Liefert eine Liste aller Entry-Objekte zurueck, sortiert nach entryField |
allEntries = entry.objects.all() | Liefert eine Liste aller Entryobjekte zurueck |
entryCount = entry.objects.all().count() | Liefert einen integer mit der Anzahl der DB-Objekte zurueck |
entryObj = entry.objects.get(pk=1) | Liefert das Object mit dem Primary Key 1 zurueck. Der Type des Objects ist die Klasse "entry" |
cheese_blog = Blog.objects.get(name="Cheddar Talk") | |
entry = entry.object.get_or_create(entryField1="field1", entryField2="field2") | Erstellt ein neues Object in der Table. Liefert ein Objekt zurueck... |
entry = entry.object.get_or_create(entryField1="field1", entryField2="field2")[0] | Erstellt ein neues Object in der Table. Liefert entryField1 zurueck... |
wanted = Entry.objects.filter(pub_date__year=2006) | get all objects, select speciic, and pass the wanted ones |
SomeModel.objects.filter(id=id).delete()
|
Loeschen eines DB-Objekts |
b5.save() | save obj to db |
Model Fields
Name | Beispiele | Beschreibung Feld | Beschreibung Parameter |
---|---|---|---|
AutoField | |||
DateField | DateField(initial=datetime.date.today)
DateField(default=date.today) |
||
CharField | |||
DecimalField | |||
ForeignKey | models.ForeignKey(Blog, on_delete=models.CASCADE) | ||
EmailField | |||
ImageField | models.ImageField(upload_to="/images/uploads", blank=True) | Blank heisst, dass dieses Feld nicht vom user ausgefuellt werden muss. | |
IntegerField | models.IntegerField(default=0) | ||
ManyToManyField | models.ManyToManyField(Author) | ||
OneToOneField | DjangoUser = models.OneToOneField(User, on_delete=models.CASCADE,) | CASCADE = Loesch das Onject, wenn Parent stirbt
RESTRICT = Loesche nur die Verbindung zu dem toten Parent PROTECT = | |
TextField | |||
URLField | models.URLField(blank=True) |
Model Attribute
unique | Boolean | Darf der Datensatz schon in der DB-Table sein? | ||
editable | Boolean | False heisst, es wird nicht im Django-Admin angezeigt. |
Form Fields
externe Doku:
https://docs.djangoproject.com/en/5.0/ref/forms/fields/
forms.BooleanField(required=False) | |||
forms.DateField(initial=datetime.date.today) | |||
forms.CharField(required=False) | |||
forms.CharField(widget=forms.TextArea, label="Your name", max_length=100) | |||
forms.CharField(label="Your name", max_length=100) | |||
forms.EmailField() | |||
forms.SubmitButtonField(label="", initial=u"Your submit button text")
|
Form Attribute
required | boolean | Muss das Feld gefuellt sein? | ||
widget=forms.HiddenInput | wird benutzt um in CharFields den bots ne falle zu stellen | |||
Template Commands
IF
{% if VARIABLE %}
<h1>Hallo {{ VARIABLE }}</h1>
{% else %}
<h1>Hallo Welt</h1>
{% endif %}
Embed HTML sourcefiles
{% extends "sourcefile.html" %}
{% include 'sourcefile.html' %}
Block
{% block block_beispiel_name %}
{% endblock %}
...endblock oder {% endblock block_beispiel_name %} funktionieren beide
Views.py Commands
Variables
x = 1
Python Config
Virtual Environment
pip3 install virtualenv
mkdir /path/to/myapp/venv
cd /path/to/myapp/venv/
virtualenv myprojectenv
source ~/myproject/myprojectenv/bin/activate
Django Config Dateien
Projekt - urls.py
Directory | Dateiname | Beschreibung |
---|---|---|
Projekt | urls.py | |
Application | urls.py | |
Application | views.py |
Django Installation
sudo apt-get install python3 python3-pip
python3 -V
Python 3.7.3
pip3 -V
pip 12.0.1 from /usr/lib/python3/dist-packages (python 3.7)
pip3 install Django
django-admin --version
2.1.2
cd /var/www
django-admin startproject django_app
cd django_app
python3 manage.py migrate
python3 manage.py createsuperuser
vi django_app/settings.py
ALLOWED_HOSTS = ['192.168.1.239']
python3 manage.py runserver 0.0.0.0:8000
http://192.168.1.239:8000/admin
Configure Static Files
vi django_app/settings.py
Fuege 2 Zeilen hinzu...
import os
und unter dem Static Verzeichnis:
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
Create new App
python manage.py startapp MyApp
cd MyApp
vi urls.py from django.urls import path
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
]
Die folgende Datei ist zustaendig fuer die Projekt URLs. Hier soll nur ein include passieren, damit die URLs in der App gemanaged werden.
cd MyProject
vi urls.py
urlpatterns = [
path("MyApp/", include("MyApp.urls")),
path('admin/', admin.site.urls),
]
cd MyApp
vi view.py
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("Halli Hallo Schwestern")
Django Errors
attempt to write a readonly database
Problem:
- Aufrufe der Seite die die Datenbank benutzen, wirft den Fehler "attempt to write a readonly database"
Lösung:
- die Datenbankdatei muss 664 als Rechtemaske haben
- das Verzeichnis muss dem Apache User und der Apache Gruppe gehören
- Die Datenbankdatei muss dem Apache User und der Apache Gruppe gehören
URL Redirecting not working
DisallowedHost - Invalid HTTP_HOST header
Problem:
Er wollte einfach nicht die IP erlauben
Loesung:
Es war ein tippfehler in der Allowed_Host Variable der Settings
ModuleNotFoundError: No module named 'MyProject'
Problem:
Der Apache schmeisst einen 500 Internal Server Error. Die Logs sagen:
ModuleNotFoundError: No module named 'MyProject'
Failed to exec Python script file '/PATH/MyProject/wsgi.py'.
mod_wsgi (pid=4996): Exception occurred processing WSGI script '/PATH/MyProject/wsgi.py'.
Traceback (most recent call last):
File "/PATH/MyProject/wsgi.py", line 16, in <module>
application = get_wsgi_application()
File "/PATH/site-packages/django/core/wsgi.py", line 12, in get_wsgi_application
django.setup(set_prefix=False)
File "/PATH/site-packages/django/__init__.py", line 19, in setup
configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
File "/PATH/site-packages/django/conf/__init__.py", line 82, in __getattr__
self._setup(name)
File "/PATH/django/conf/__init__.py", line 69, in _setup
self._wrapped = Settings(settings_module)
File "/PATH/site-packages/django/conf/__init__.py", line 170, in __init__
mod = importlib.import_module(self.SETTINGS_MODULE)
File "/usr/lib/python3.7/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 965, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'MyProject'
Loesung:
In der wsgi.py nen import und nen Pfad hinzufuegen...
import sys
sys.path.append('/PATH/MyProject')
ModuleNotFoundError: No module named 'importlib_metadata'
Loesung
Manuelles nachinstallieren der Lib... pip3 install importlib_metadata