[PYTHON] Django Memorandum

Ich habe vor ungefähr einem Jahr eine kleine App über Django geschrieben, aber ich habe sie vergessen, deshalb werde ich mich daran erinnern, während ich sie als Memorandum hinterlasse. Ich habe die neuesten Tutorials in der offiziellen Dokumentation verglichen, da die japanische Übersetzung des Tutorials nur 1.4 ist, was eine ziemlich alte Version ist, aber der Artikel hier Ich erinnere mich, dass es sehr hilfreich war.

1.8 ist bereits herausgekommen, aber da ich es das letzte Mal in 1.7 gemacht habe, wird es in 1.7 herauskommen.

Umgebung in diesem Artikel

[sayamada@~]$cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.04
DISTRIB_CODENAME=precise
DISTRIB_DESCRIPTION="Ubuntu 12.04.5 LTS"
[sayamada@~]$uname -a
Linux XXXXXX 3.13.0-65-generic #106~precise1-Ubuntu SMP Fri Oct 2 22:07:14 UTC 2015 i686 i686 i386 GNU/Linux
[sayamada@~]$python -V
Python 2.7.9 :: Anaconda 2.0.1 (32-bit)
[sayamada@~]$pip list |grep -i django
Django (1.7.1)
django-bootstrap-form (3.1)

Ich kann auf einem Firmen-PC keine Wurzeln schlagen, also benutze ich Anaconda, um den Tee schlammig zu machen. Gewöhnliche Leute

$ pip install django==1.7.1

Ist es nicht okay?

Erstellen Sie ein Projekt

Entspricht eine Website einem Projekt? Zuerst habe ich ein Projekt gemacht.

[sayamada@git]$django-admin.py startproject demoPrj
[sayamada@git]$tree demoPrj/
demoPrj/
├── demoPrj
│   ├── __init__.py
│   ├── settings.py --Der Typ, der die Einstellungen schreibt
│   ├── urls.py  --Der Typ, der das Top-Routing schreibt
│   └── wsgi.py
└── manage.py --Ausführungsskript für Verwaltungsbefehle

Backend-DB-Änderungen

Es scheint standardmäßig mit SQLite zu funktionieren, aber ich mag das Berufsmuster PostgreSQL, also werde ich es ändern. ** pyscopg2 ** Ich habe das Gefühl, ich musste es hinzufügen. Wenn Sie PostgreSQL nicht mögen, können Sie einfach SQLite verwenden.

settings.py


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'DB-Name',
        'USER': 'Nutzername',
        'PASSWORD': '',
        'HOST': 'localhost',
        'PORT': '5432'
    }
}

Gebietsschema ändern

Ich bin Japaner, also werde ich es ändern.

settings.py


# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'ja'

# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Tokyo'

Eine Anwendung erstellen

Es scheint, dass die Site (das Projekt) aus mehreren ** Anwendungen ** besteht. Möchten Sie für jede Funktion eine App erstellen und hinzufügen? Was ist es?

[sayamada@git]$cd demoPrj/
[sayamada@demoPrj]$python manage.py startapp demoApp
[sayamada@demoPrj]$tree 
.
├── demoApp --Dieses Verzeichnis hat zugenommen
│   ├── __init__.py
│   ├── admin.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py --Derjenige, der das Modell definiert
│   ├── tests.py 
│   └── views.py --Ein Typ, der VIEW oder logische Einstiegspunkte schreibt?
├── demoPrj
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── settings.py
│   ├── settings.pyc
│   ├── urls.py
│   └── wsgi.py
└── manage.py

3 directories, 13 files

Übrigens, obwohl es nicht standardmäßig erstellt wird, scheint es, dass in demoPrj / urls.py ein großes Routing definiert ist und das Routing für jede Anwendung individuell festgelegt wird. Erstellen Sie also ** demoApp / urls.py ** manuell. ..

Benutzerauthentifizierung

django definiert im Voraus ein Modell (** Benutzer **) für die Kontoverwaltung. Middleware zur Authentifizierung ist ebenfalls verfügbar. Dieses Mal habe ich den Authentifizierungsprozess in einer Anwendung namens ** Auth ** erstellt, sodass ich ihn auch zu INSTALLED_APPS hinzufügen werde.

settings.py


INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',★ Damit
    'django.contrib.contenttypes',★ Ich brauche das
:
    'Authctl',★ Dies wurde mit startapp gemacht
:
LOGIN_URL = '/auth/login'
LOGIN_REDIRECT_URL = '/auth/home'
:
AUTHENTICATION_BACKENDS = (
    'Authctl.AuthLogic.AuthBackEnd',
    'django.contrib.auth.backends.ModelBackend',
)

Es ist enthalten, wenn das Projekt erstellt wird. Geben Sie danach die Authentifizierungslogik in AUTHENTICATION_BACKENDS an. Oben ist die Authentifizierungslogik, die ich gemacht habe. Ich habe vergessen, warum es zwei gibt. Die Ansichtsseite der Seite, für die eine Authentifizierung erforderlich ist, lautet wie folgt. Dieses Mal habe ich AuthLogic.py unter Auth erstellt und beschlossen, darin eine Funktion namens AuthBackend zu definieren.

demoApp/views.py


# coding:utf-8
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required

@login_required
def index(request):
    return HttpResponse(u'Index')

Die Methode mit dem Dekorator login_required wird im Voraus überprüft, um festzustellen, ob sie angemeldet ist. Wenn Sie nicht angemeldet sind, werden Sie in settings.py zu ** LOGIN_URL ** weitergeleitet. Diesmal ist es / authctl / login, daher müssen Sie das Routing konfigurieren, um es zu beheben.

Wenn in forms.ModelForm ein Feld ausgeschlossen ist

Zum Zeitpunkt von form.save liegt ein Fehler aufgrund der NOT NULL-Einschränkung vor. Sie können eine Instanz von Model mit Attributen, die durch ** instance = ** ausgeschlossen sind, an den Formularkonstruktor übergeben.

views.py


any_model_inst = AnyModel()
any_model_inst.excluded_any_ked = u"hoge"
form = AnyForm(request.POST, instance=any_model_inst)
form.save()

Anforderungsobjekt im Dekorator anzeigen

Ich weiß nicht, wo sich das Anforderungsobjekt befindet.

#Dekorateur zur Überprüfung, ob der API-Zugriff berechtigt ist
def check_access_permission(func):
    import functools
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        #Das erste Argument ist das Anforderungsobjekt
        request = args[0]
        print request.user
        if check_any_func():
            return HttpResponseForbidden()
        # OK
        return func(*args, **kwargs)
    return wrapper

Ich wollte den Authorization-Header sehen

Ich wollte den Header sehen, als ich so etwas warf

curl localhost:8000/api/ \
-H "Authorization: demo token" \
-X GET 

Es war so

def check_access_permission(func):
    import functools
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        #Das erste Argument ist das Anforderungsobjekt
        request = args[0]
        #Sie können es damit bekommen
        print request.META.get('HTTP_AUTHORIZATION')
        if False:
            return HttpResponseForbidden()

        return func(*args, **kwargs)
    return wrapper

Ich wollte so etwas wie ENUM mit Form machen

Als ich den von REST angegebenen Wert eingrenzen wollte, habe ich ein Formular nur für die Validierung erstellt, und Choice Fileld war genau richtig

forms.py


    contact_choice = (
        ("TEL", "TEL"),
        ("Email", "Email"),
        ("FAX", "FAX"),
        ("Web", "Web"),
    )
    contact_way = forms.ChoiceField(label=u"Anfragemethode", choices=contact_choice,required=False, initial=None)

Wenn Sie in contact_way hoge eingeben, sterben Sie mit is_valid ().

Ich möchte wissen, warum gültig in Form fehlgeschlagen ist

Es wurde ordnungsgemäß in Manual geschrieben. Es scheint, dass es verschiedene Möglichkeiten gibt, es nach 1.7 anzuzeigen.

if form.is_valid():

    something doing..
else:
        # FromClass.Es gibt Fehler in Fehlern
        # as_json()Kann im JSON-Format mit abgerufen werden
        print  form.errors.as_json()

Die Formularinitiale wird nicht mit bereinigten_Daten abgerufen

sender_name = forms.CharField(label=u'Absender', required=False, initial=u"default sender")

Also, wenn Sie das tun

sender_name = form.cleaned_data["sender_name"] # -> I expect "default sender" but None

Es ist geworden.

Wenn Sie [hier] betrachten (http://stackoverflow.com/questions/9069705/form-cleaned-data-is-ignoring-initial-values), scheint es, dass initial die anfänglichen Daten auf dem Display sind und nicht mit bereinigten_Daten abgerufen werden können. Es sieht so aus, als müssten Sie form.clean überschreiben. Es gab einen Teil, der sich nicht ein wenig bewegte, also habe ich ihn schließlich durch den folgenden ersetzt.

class DisplaySharerForm(forms.Form):
...
    def clean(self):
        cleaned_data = super(DisplaySharerForm, self).clean()
        for key, value in cleaned_data.items():
            if not value:
                cleaned_data[key] = self.fields[key].initial

        return cleaned_data

Recommended Posts

Django Memorandum
Django
Matplotlib Memorandum
Django-Update
Django Note 4
Linux Memorandum
jinja2 Memorandum
Python-Memorandum
Django-Suche
Django Installation
Befehlsmemorandum
Django Zusammenfassung
Django-Test
Python-Memorandum 2
[Django] Memorandum of Environment Construction Procedure
Plotly Memorandum
Slackbot-Memorandum (1)
Multiprocessing Memorandum
Memorandum MetaTrader5
Django # 2 (Vorlage)
ShellScript-Memorandum
Django Note 5
Django zum Anfassen
Berühre Django
Django Memo
Django Zusammenfassung
Django Grundlagen
Pip Memorandum
Django Shoho
Python-Memorandum
Django Grundeinstellungen
Pydoc Memorandum
Django + Docker
Python Memorandum
Memorandum of Pandas
Python Memorandum
DjangoGirls Memorandum
Django Glossar
Django Installation
Befehlsmemorandum
Django: Referenzen
Python-Memorandum
Django Note 1
Pandas Memorandum
Python Memorandum
Django Note 3
Django Note 2
Python-Memorandum
Django-Start
Django Memo
Django NullCharField
Django Umweltbau
Python-Grundmemorandum
Memorandum vom RAID-Typ
Django Heroku Deploy 1
Django HTML Vorlage Teil 2
Django Anfrageformular 2
Django startete Teil 1
Python Pathlib Memorandum