Skip to content
Chetabahana edited this page May 5, 2019 · 237 revisions

Dalam sesi ini, kita akan bahas tentang penyetelan untuk kerangka kerja Django.

Table of Contents

Arsitektur

Memulai

$ source virtual-env/bin/activate
(virtual-env)$ pip install Django
(virtual-env)$ python -m django --version
2.2
(virtual-env)$ export DJANGO_SETTINGS_MODULE=mysite.settings
(virtual-env)$ django-admin help
Type 'django-admin help <subcommand>' for help on a specific subcommand.
Available subcommands:
[django]
    check
    compilemessages
    createcachetable
    dbshell
    diffsettings
    dumpdata
    flush
    inspectdb
    loaddata
    makemessages
    makemigrations
    migrate
    runserver
    sendtestemail
    shell
    showmigrations
    sqlflush
    sqlmigrate
    sqlsequencereset
    squashmigrations
    startapp
    startproject
    test
    testserver

Project

(virtual-env)$ django-admin startproject saleor
saleor/
    manage.py
    saleor/
        __init__.py
        settings.py
        urls.py
        wsgi.py
    static/
    templates/
file mapping dokumentasi
saleor/ fork directory / branch directory / virtual-env saleor
manage.py set("DJANGO_SETTINGS_MODULE", "saleor.settings")
from django.core.management import execute_from_command_line
Arsitektur
saleor/__init__.py from .celeryconf import app as celery_app Celery
saleor/settings.py ROOT_URLCONF = 'saleor.urls'
WSGI_APPLICATION = 'saleor.wsgi.application'
Setting
saleor/urls.py from django.conf import settings URL-Router
saleor/wsgi.py from django.core.wsgi import get_wsgi_application Web-Gateway
static/
media/
STATICFILES_STORAGE / DEFAULT_FILE_STORAGE
django.contrib.staticfiles.storage.StaticFilesStorage
django.core.files.storage.FileSystemStorage
Static URL
templates/ templates directory Templates

Aplikasi

(virtual-env)$ cd saleor 
(virtual-env)$ python manage.py runserver
(virtual-env)$ python manage.py startapp products
saleor/
    manage.py
    saleor/
        products/
            migrations/
                __init__.py
            models.py
            tests.py
            views.py        
        __init__.py
        settings.py
        urls.py
        wsgi.py
    static/
    templates/
        products/

Cara Kerja

Setting

URL Router

Untuk pemetaan URL aplikasi, Django membuat modul Python yang disebut URLconf (konfigurasi URL). Modul ini merupakan mapping antara ekspresi jalur URL ke fungsi Python (views).

implementasi
file mapping dokumentasi
saleor/urls.py from django.conf import settings Configuration

Web Gateway

Static URL

Dengan DEBUG diaktifkan, Django menyajikan file statis untuk Anda. Jika Anda menonaktifkannya, server Anda harus ambil-alih.

File Gambar

SCRIPT_NAME=/market
MEDIA_URL=/market/media/
STATIC_URL=/market/static/

File js/css

  1. Pastikan file webpack.config.js Anda terbaru. Tetapi, jika Anda tidak menggunakan cabang master, gunakan versi webpack.config.js karena file lokal tidak akan kompatibel dengan master terbaru (<= 2018.07);
  2. Anda perlu mengatur STATIC_URL ke URL bucket Anda (ke direktori aset induk);
  3. Jalankan npm run build-assets --produksi; Pastikan file aset bucket Anda dikompilasi menggunakan --produksidjango.conf, jika tidak, jalankan kembali collectstatics untuk memperbarui bucket;
  4. Start ulang Saleor.

Templates

Secara detil setiap page di atas diproduksi seperti berikut

Konfigurasi

Core

init.py

manage.py

#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dummy.settings')
    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)


if __name__ == '__main__':
    main()

Setelan

urls.py

urlpatterns = non_translatable_urlpatterns + i18n_patterns(
    *translatable_urlpatterns)

if settings.DEBUG:
    import debug_toolbar
    urlpatterns += [
        url(r'^__debug__/', include(debug_toolbar.urls)),
        # static files (images, css, javascript, etc.)
        url(r'^static/(?P<path>.*)$', serve)] + static(
            '/media/', document_root=settings.MEDIA_ROOT)
Anda dapat mengasumsikan, bahwa request melewati urlpatterns dari atas ke bawah dengan pola yang pertama yang cocok (Y) akan dieksekusi seperti analogi berikut:

  • jika Y sebelum X: maka pola Y akan dieksekusi (tetapi tidak selalu seharusnya)
  • jika X adalah sebelum Y: pola X tidak cocok dengan url (tetapi harus didahulukan)

wsgi.py

Web Server Gateway Interface (WSGI) adalah konvensi untuk meneruskan URL ke aplikasi web atau kerangka kerja yang ditulis dalam bahasa pemrograman Python.

Untuk project saleor pengembang menggunakan uwsgi yang disetel fia Dockerfile:

CMD ["uwsgi", "--ini", "/app/saleor/wsgi/uwsgi.ini"]
Untuk pemasangan di GCP maka sesuai arahan kita pakai gunicorn via entry di app.yaml:
entrypoint: gunicorn -b :$PORT saleor.wsgi --timeout 120
Pembahasan lebih lanjut silahkan simak di sesi Gunicorn.

settings.py

Untuk file static/media sesuai requirements.txt Aplikasi Saleor menggunakan django-storages: versi 1.7.1 disetel di settings.py ke AWS Storage via migrasi boto3 library sebagai berikut:

if AWS_STORAGE_BUCKET_NAME:
    STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

if AWS_MEDIA_BUCKET_NAME:
    DEFAULT_FILE_STORAGE = 'saleor.core.storages.S3MediaStorage'
    THUMBNAIL_DEFAULT_STORAGE = DEFAULT_FILE_STORAGE

Catatan:

Pembahasan lebih lanjut silahkan simak di sesi setelan GCP Storage.

Penerapan

views.py

models.py

migrate.py

Pengembangan

Struktur

Non Root

Setel: FORCE_SCRIPT_NAME
Default: Tidak Ada (None)

Jika tidak ada (None), maka akan digunakan sebagai nilai variabel lingkungan SCRIPT_NAME dalam permintaan HTTP apa pun.

Pengaturan ini dapat digunakan untuk mengganti nilai SCRIPT_NAME yang disediakan server, yang mungkin merupakan versi yang ditulis ulang dari nilai default atau tidak disediakan sama sekali.

Ini juga digunakan oleh django.setup () untuk menetapkan awalan skrip penyelesai URL di luar siklus permintaan / respons (mis. Dalam perintah manajemen dan skrip mandiri) untuk menghasilkan URL yang benar ketika SCRIPT_NAME tidak /.

settings.py
FORCE_SCRIPT_NAME = "/django/sample/"

Case

test

http://server/django/sample/admin
hasil
http://server/django/sample/django/sample/admin

Nginx

setelan untuk nginx.conf sbb:

location /django/sample {
    fastcgi_split_path_info ^(/django/sample)(.*)$;
    include fastcgi_params;
    fastcgi_pass 127.0.0.1:8025;
}

Apache

setelan untuk apache.conf sbb:

settings.py:

SUB_SITE = "/donut/"

wsgi.py

import os, sys
sys.path.append('/path/to') #parent directory of project
sys.path.append('/path/to/donut_code')
#You might not need this next line. 
# But if you do, this directory needs to be world-writable.
os.environ['PYTHON_EGG_CACHE'] = '/path/to/.python-eggs'
os.environ['DJANGO_SETTINGS_MODULE'] = 'donut_code.settings'

import django.core.handlers.wsgi

_application = django.core.handlers.wsgi.WSGIHandler()
def application(environ, start_response):
    environ['PATH_INFO'] = environ['SCRIPT_NAME'] + environ['PATH_INFO']
    environ['SCRIPT_NAME'] = '' # my little addition to make it work
    return _application(environ, start_response)

urls.py

from django.conf.urls.defaults import *
import settings

urlpatterns = patterns('',
    (r'^%s/' % settings.SUB_SITE, include('urls_subsite')),
)

settings.py:

from django.conf.urls.defaults import *
import settings

# NOTE: I don't really like defining this here, but the only other place it
# should logically go is in an overall site-level app.  Seems like too much
# overhead.
from django.shortcuts import Http404
def no_view(request):
    """
    We don't really want anyone going to the static_root.
    However, since we're raising a 404, this allows flatpages middleware to
    step in and serve a page, if there is one defined for the URL.
    """
    raise Http404

urlpatterns = patterns('',
    #Normal includes for app URLs:
    (r'^accounts/', include('accounts.urls')),

    # Special URL defined here, so that we have DRY in templates, without RequestContext.
    url(r'site_media/$', no_view, name='static_root'),
)

urls_subsite.py:

from django.conf.urls.defaults import *
import settings

# Enable the Django admin:
from django.contrib import admin
admin.autodiscover()

# NOTE: I don't really like defining this here, but the only other place it
# should logically go is in an overall site-level app.  Seems like too much
# overhead for this two little, very simple views.
from django.shortcuts import render_to_response, Http404
from django.contrib.auth.decorators import login_required
from django.template import RequestContext
@login_required
def welcome_view(request):
    return render_to_response('welcome.html',
                              context_instance=RequestContext(request))

def no_view(request):
    """
    We don't really want anyone going to the static_root.
    However, since we're raising a 404, this allows flatpages middleware to
    step in and serve a page, if there is one defined for the URL.
    """
    raise Http404

urlpatterns = patterns('',
    # Uncomment the next line to enable the admin:
    (r'^admin/', include(admin.site.urls)),

    # Enable language switching.  This way, you can write a template that POSTs 
    # to {% url set_language %}.
    url(r'^i18n/setlang/$', 'django.views.i18n.set_language',
        name="set_language"),
    (r'^i18n/setlang/$', include('django.conf.urls.i18n')),

    # Other app views
    (r'^accounts/', include('accounts.urls')),
    (r'^holes/', include('holes.urls')),
    (r'^fillings/', include('fillings.urls')),

    # A welcome page at the SUB_SITE root.
    url(r'^$', welcome_view, name='welcome'),

    # URLs defined here, so that we have DRY in templates, without RequestContext.
    url(r'site_media/$', no_view, name='static_root'),
   # This next one lets me use {% url help_root %} in templates.
    # Practically, I'm using flatpages to handle any help documents.
    # This means I'll have to update each flatpage's URL if I move the SUB_SITE.
    # Not too bad, esp. if I use Django's ORM to update them.
    url(r'help/$', no_view, name='help_root'),
)

if settings.DEBUG:
    urlpatterns += patterns('',
        # Uncomment on non-production servers, if you want to debug with "runserver":
        # For static files during DEBUG mode:
        (r'^site_media/(?P.*)$', 'django.views.static.serve',
            {'document_root': '/path/to/donut/static/' }),

Building

Static_URL disetel via Dockerfile yang diatur berdasarkan nilai lingkungan

### Build static assets
FROM node:10 as build-nodejs

ARG STATIC_URL
ENV STATIC_URL ${STATIC_URL:-/static/}

Nilai ini akan berlaku bagi template:

# Build static
COPY ./saleor/static /app/saleor/static/
COPY ./templates /app/templates/
RUN STATIC_URL=${STATIC_URL} npm run build-assets --production \
  && npm run build-emails --production
Yang kemudian image dikoleksi sbb:
### Final image
FROM python:3.6-slim

RUN SECRET_KEY=dummy STATIC_URL=${STATIC_URL} python3 manage.py collectstatic --no-input

Workspace

Symlinks

STATICFILES_DIRS	
[('assets', '/srv/saleor/static/assets'),
 ('favicons', '/srv/saleor/static/favicons'),
 ('images', '/srv/saleor/static/images'),
 ('dashboard/images', '/srv/saleor/static/dashboard/images')]
STATICFILES_FINDERS	
['django.contrib.staticfiles.finders.FileSystemFinder',
 'django.contrib.staticfiles.finders.AppDirectoriesFinder']
STATICFILES_STORAGE	
'django.contrib.staticfiles.storage.StaticFilesStorage'
STATIC_ROOT	
'/srv/static'
STATIC_URL	
'/market/static/'
STRIPE	
'stripe'
TEMPLATES	
[{'BACKEND': 'django.template.backends.django.DjangoTemplates',
  'DIRS': ['/srv/templates'],

Referensi

Project Tutorial

You are on the wiki of our repo

Chetabahana Project

Clone this wiki locally