Djangoでユーザ毎に言語設定できるようにしてみた

やったこと

  1. ブラウザの言語設定に応じた言語を表示する。
    • 日本語設定のブラウザなら日本語で、英語設定のブラウザなら英語でWebサイトを表示する。
    • 技術的にはDjangoの国際化(i18n)を利用してAccept-Languageの優先順位が高い言語でページを生成する。
  2.  Djangoのアカウント機能と合わせて、各ユーザが指定した言語に合わせてページを表示させる。
    • 技術的にはDjangoのセッション情報(session['_language'])を任意のタイミングで書き換える。

ちなみにソースコードはGitHubにもあります。

目次

  • 環境の準備
  • ブラウザの言語設定に応じたページ表示
  • アカウント認証機能の追加
  • ユーザ毎に言語設定機能の追加

環境の準備

本記事は以下の環境で実行した。

  • OS: CentOS7.6
  • Python 3.6.7
  • Django 2.1

以下のコマンドで諸々インストール

$ sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm
$ sudo yum install -y python36u python36u-libs python36u-devel python36u-pip
$ sudo pip3.6 install django==2.1

ブラウザの言語設定に応じたページ表示

Djangoプロジェクトを作成する。

$ cd ~
$ django-admin startproject i18n
$ cd i18n

i18n/settings.pyを編集する。(ファイル名は~/i18n/からの相対パス。以後同様)

# どのホストからのアクセスも受け付ける
ALLOWED_HOSTS = ['*']

# 国際化のミドルウェアを追加
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware', # 追加
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates'),], # 変更
'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',
],
},
},
]

# デフォルトの言語を日本語にする
LANGUAGE_CODE = 'ja'

# localeフォルダの位置を指定する
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale'),
)

# 選択できる言語を設定する
from django.utils.translation import ugettext_lazy as _
LANGUAGES = [
('en', _('English')),
('ja', _('Japanese')),
]

i18n/urls.pyを編集する。

from django.contrib import admin
from django.urls import path
from . import views # 追加

urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index, name='index'), # 追加
]

i18n/views.pyを作成する。

from django.shortcuts import render

def index(request):
return render(request, 'index.html')

templatesフォルダを作成する。

templates/index.htmlを作成する。

{% load i18n %}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>{% trans "Djangoのテストページ" %}</title>
</head>
<body>
<h1 id="title">{% trans "Djangoのテストページ" %}</h1>
<button type="button" onclick='alert("{% trans "こんにちは" %}")'>{% trans "ここをクリック" %}</button>
</body>
</html>

localeフォルダを作成する。

以下のコマンドで翻訳用ファイルを作成する。

$ django-admin makemessages -l en

locale/en/LC_MESSAGES/django.poを編集する。

# : i18n/templates/index.html:6 i18n/templates/index.html:9
msgid "Djangoのテストページ"
msgstr "Django test page" # 変更

# : i18n/templates/index.html:10
msgid "こんにちは"
msgstr "Hello" # 変更

# : i18n/templates/index.html:10
msgid "ここをクリック"
msgstr "Click here" # 変更

以下のコマンドで翻訳ファイルをコンパイルする。

$ django-admin compilemessages

Webサーバ起動

$ python3.6 manage.py runserver 0.0.0.0:8000

ブラウザでhttp://(仮想マシンのIPアドレス):8000にアクセスし、ブラウザの言語設定に応じたページが表示されることを確認する。

ブラウザの言語設定に応じたページ(日本語)
ブラウザの言語設定に応じたページ(英語)

アカウント認証機能の追加

i18n/settings.pyを編集してログインURL設定を追加する。

LOGIN_URL = '/login/'

i18n/urls.pyにログインとログアウトのエンドポイントを追加する。
※:ログインにはdjango.contrib.auth.views.LoginViewを使うのが簡単なのだが、今回はアカウント毎に言語を設定する処理を追加するため低水準関数のdjango.contrib.authauthenticateloginを利用する。

from django.contrib import admin
from django.urls import path
from . import views

urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index, name='index'),

path('login/', views.login_view, name="login"), # ログイン用エンドポイント追加
path('logout/', views.logout_view, name='logout'), # ログアウト用エンドポイント追加
]

i18n/views.pyにログインとログアウトの処理を追加する。

from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login
from django.contrib.auth import views as auth_views

@login_required # トップページもログインしないと入れないようにしてみる
def index(request):
return render(request, 'index.html')

# ログイン用view関数を追加
def login_view(request):
if request.method == 'GET':
next = request.GET.get('next', '/')
return render(request, 'login.html', {'next': next})
elif request.method == 'POST':
username = request.POST.get('username', '')
password = request.POST.get('password', '')
next = request.POST.get('next', '/')
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return redirect(next)
else:
return render(request, 'login.html', {'next': next, 'error': True})

# ログアウト用view関数を追加
@login_required
def logout_view(request):
return auth_views.logout_then_login(request)

トップページtemplates/index.htmlにログアウトボタンを追加する。

{% load i18n %}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>{% trans "Djangoのテストページ" %}</title>
</head>
<body>
<h1 id="title">{% trans "Djangoのテストページ" %}</h1>
<button type="button" onclick='alert("{% trans "こんにちは" %}")'>{% trans "ここをクリック" %}</button>
<!-- ここを追加 -->
<form action="{% url 'logout' %}">
<input type="submit" value="{% trans "ログアウト" %}" />
</form>
<!-- 追加ここまで -->
</body>
</html>

ログイン用テンプレートtemplates/login.htmlを作成

{% load i18n %}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>{% trans "ログイン" %}</title>
</head>
<body>

<h1 id="title">{% trans "ログイン" %}</h1>
{% if error %}
<p>{% trans "ユーザ名もしくはパスワードが間違っています。もう一度試してください。" %}</p>
{% endif %}

<form method="post" action=".">
{% csrf_token %}
<table>
<tr><td>{% trans "ユーザ名" %}: </td><td><input type="text" name="username"></td></tr>
<tr><td>{% trans "パスワード" %}: </td><td><input type="password" name="password"></td></tr>
</table>
<input type="hidden" name="next" value="{{ next }}">
<input type="submit" value="{% trans "ログイン" %}" />
</form>
</body>
</html>

翻訳用ファイルを更新する。

$ django-admin makemessages -l en

locale/en/LC_MESSAGES/django.poを編集する。

# : templates/index.html:14
msgid "ログアウト"
msgstr "Log out" # 変更

# : templates/login.html:6 templates/login.html:10 templates/login.html:23
msgid "ログイン"
msgstr "Log in" # 変更

# : templates/login.html:12
msgid "ユーザ名もしくはパスワードが間違っています。もう一度試してください。"
msgstr "Your username and password didn't match. Please try again." # 変更

# : templates/login.html:18
msgid "ユーザ名"
msgstr "Username" # 変更

# : templates/login.html:20
msgid "パスワード"
msgstr "Password" # 変更

翻訳ファイルをコンパイルする。

$ django-admin compilemessages

以下の2つのコマンドでDBマイグレーションを実施する。

$ python3.6 manage.py makemigrations
$ python3.6 manage.py migrate

adminユーザを作成する。

$ python3.6 manage.py createsuperuser
ユーザー名 (leave blank to use 'root'): admin
メールアドレス: (空欄でも可)
Password: (パスワード)
Password (again): (パスワード)
Superuser created successfully.

Webサーバ起動

$ python3.6 manage.py runserver 0.0.0.0:8000

ブラウザでhttp://(仮想マシンのIPアドレス):8000にアクセスし、以下を確認する。

  • ログインページにリダイレクトされる。
    ログインページ(日本語)

    ログインページ(英語)
  • ログインするとトップページに遷移する。
    ログイン後のトップページ(日本語)

    ログイン後のトップページ(英語)
  • 「ログアウト」をクリックするとログアウト処理が行われ、再度ログインページにリダイレクトされる。

ユーザ毎に言語設定機能の追加

i18n/models.pyを作成してDBモデルを追加する。
※:アカウント毎の言語を設定できるようにするため、Userテーブルと1対1関係にあるProfileテーブルを作成してProfileに言語を格納する。

from django.db import models
from django.contrib.auth.models import User

class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
language = models.CharField(max_length=128, default='', blank=True) # ユーザの設定した言語を格納する

def __str__(self):
return self.user.username

管理画面でDB設定できるようにi18n/admin.pyを作成する。

from django.contrib import admin
from .models import Profile

# Register your models here.
@admin.register(Profile)
class Profile(admin.ModelAdmin):
pass

i18n/settings.pyを編集して、Profileモデルを読み込めるようにする。

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'i18n', # 追加
]

i18n/urls.pyに言語設定用のエンドポイントを追加する。

from django.contrib import admin
from django.urls import path
from . import views

urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index, name='index'),

path('login/', views.login_view, name="login"),
path('logout/', views.logout_view, name='logout'),

path('language/', views.language, name='language'), # 追加
]

i18n/views.pyに言語設定の処理を追加する。
また、ログイン時に設定してある言語を適用する処理も追加する。

from django.shortcuts import render, redirect, get_object_or_404 # 便利な関数を追加
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login
from django.contrib.auth import views as auth_views
from .models import Profile # 追加

@login_required
def index(request):
return render(request, 'index.html')

# ログイン用view関数を編集
def login_view(request):
if request.method == 'GET':
next = request.GET.get('next', '/')
return render(request, 'login.html', {'next': next})
elif request.method == 'POST':
username = request.POST.get('username', '')
password = request.POST.get('password', '')
next = request.POST.get('next', '/')
print(next)
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
profile = get_object_or_404(Profile, user=request.user) # Profileテーブルから該当のユーザを取得
request.session['_language'] = profile.language # この通信のsessionに言語を設定する
return redirect(next)
else:
return render(request, 'login.html', {'next': next, 'error': True})

# ログアウト用view関数を編集
@login_required
def logout_view(request):
del request.session['_language'] # このsessionの言語設定を削除する
return auth_views.logout_then_login(request)

# 言語設定用view関数を追加
@login_required
def language(request):
if request.method == 'GET':
return render(request, 'language.html')
elif request.method == 'POST':
language = request.POST['language']
profile = get_object_or_404(Profile, user=request.user) # Profileテーブルから該当のユーザを取得
profile.language = language # Profileにユーザからのリクエスト言語を設定
profile.save() # DB更新
request.session['_language'] = language # この通信のsessionに言語を設定する

return redirect('language')

request.session['_language']でセッション情報の言語設定を上書きすることがミソ。

トップページtemplates/index.htmlに言語設定ページへのリンクを追加する。

{% load i18n %}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>{% trans "Djangoのテストページ" %}</title>
</head>
<body>
<h1 id="title">{% trans "Djangoのテストページ" %}</h1>
<button type="button" onclick='alert("{% trans "こんにちは" %}")'>{% trans "ここをクリック" %}</button>
<!-- ここを追加 -->
<br/>
<a href="{% url 'language' %}">{% trans "言語設定" %}</a>
<!-- 追加ここまで -->
<form action="{% url 'logout' %}">
<input type="submit" value="{% trans "ログアウト" %}" />
</form>
</body>
</html>

言語設定用テンプレートtemplates/language.htmlを作成する。

{% load i18n %}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>{% trans "言語設定ページ" %}</title>
</head>
<body>
<h1 id="title">{% trans "言語設定ページ" %}</h1>
<form action="." method="post">
{% csrf_token %}
<select name="language">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>
{{ language.name_local }} ({{ language.code }})
</option>
{% endfor %}
</select>
<input type="submit" value="{% trans "変更" %}">
</form>

<a href="{% url 'index' %}">{% trans "トップページに戻る" %}</a>

</body>
</html>

あとは翻訳系の作業。翻訳用ファイルを更新する。

$ django-admin makemessages -l en

locale/en/LC_MESSAGES/django.poを編集する。

# : templates/index.html:12
msgid "言語設定"
msgstr "Language setting" # 変更

# : templates/language.html:6 templates/language.html:9
msgid "言語設定ページ"
msgstr "Language setting page" # 変更

# : templates/language.html:22
msgid "変更"
msgstr "Change" # 変更

# : templates/language.html:25
msgid "トップページに戻る"
msgstr "Back to top page" # 変更

翻訳ファイルをコンパイルする。

$ django-admin compilemessages

DBマイグレーション

$ python3.6 manage.py makemigrations i18n
$ python3.6 manage.py migrate

Webサーバ起動

$ python3.6 manage.py runserver 0.0.0.0:8000

ブラウザで管理者ページhttp://(仮想マシンのIPアドレス):8000/adminにアクセスし、adminユーザのProfileを作成する。

管理者ページにアクセス。adminユーザでログインする。
このページでDBデータを操作できる。
Profileテーブルにadminユーザのデータを登録。Languageは空でOK。

管理者ページからログアウトし、トップページにアクセスして以下を確認する。(ログインは前項と同じなので省略)

  • 「言語設定」リンクがあること

    トップページに「言語設定」リンクが表示される。(日本語設定のブラウザの場合)
  • 「言語設定」リンクを押すと言語設定ページが表示されること

    言語設定ページで言語選択できる。
  • プルダウンから英語を設定して「変更」をクリックすると英語のページが表示されること

    言語設定を英語に変更すると英語表記のページが表示される
  • トップページに戻ると自分が設定した言語のまま

    トップページに戻っても英語のまま。
  • ログアウトするとブラウザ本来の言語でログインページが表示されること

    ログアウトするとブラウザ本来の言語に戻る。

Djangoをmod_wsgiで動かす(CentOS7, Python2.7)

環境

  • CentOS: 7.3
  • Apache: 2.4.6
  • mod_wsgi: 3.4
  • Python: 2.7
  • Django: 1.11

Djangoの設定

Djangoのsettings.pyに以下の設定を追加し、デプロイ時のstaticディレクトリを指定する

STATIC_ROOT = "/var/www/static/"

デプロイユーザの作成

デプロイ用のユーザとしてwww-dataを追加。

ユーザ作成後はホームディレクトリにDjangoプロジェクトのデータを持ってくる。
(下の例ではgitからclone)

また、Apacheユーザからアクセスするためにはホームディレクトリに実行権限を持たせる必要があるため権限を変更する。

# useradd www-data -g apache
# su - www-data
$ git clone (gitリポジトリのURL)
$ exit
# chmod 770 /home/www-data/

staticディレクトリの作成

静的ファイルは専用のディレクトを用意。

その後、collectstaticコマンドで静的ファイルをコピーする。

こちらもApacheユーザ権限を追加する。

# mkdir /var/www/static
# chown www-data:apache /var/www/static
# su - www-data
$ cd (gitリポジトリ名)
$ python manage.py collectstatic
$ exit
# chmod -R 775 /var/www/static

Apacheの設定ファイルを編集

/etc/httpd/conf/httpd.confを編集し、以下を追記する。

以下の例は最小限の設定内容を記載している。

WSGIScriptAlias / /home/www-data/(gitリポジトリ名)/(Djangoプロジェクト名)/wsgi.py
WSGIPythonPath /home/www-data/(gitリポジトリ名)
Alias /static/ /var/www/static/

<Directory /home/www-data/(gitリポジトリ名)/(Djangoプロジェクト名)>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
<Directory /var/www/static>
Order deny,allow
Allow from all
</Directory>

Apacheの再起動

systemctl restart httpd

確認

ブラウザで「http://127.0.0.1/」にアクセス

Djangoのモデル作成

Djangoでモデルを作成する方法の備忘録。

前回の投稿の続き

アプリの作成

$ python manage.py startapp api

mysite/settings.py

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'api', # 追記
]

モデルの作成

api/models.py

# 以下を追記
class Table(models.Model):
name = models.CharField(max_length=128, default="")

def __str__(self):
return self.name

api/admin.py

# 以下を追記
from .models import Table

# Register your models here.
@admin.register(Table)
class Table(admin.ModelAdmin):
pass

データベースファイルの作成

$ python manage.py makemigrations
$ python manage.py migrate

実行と確認

$ python manage.py runserver 0.0.0.0:8000

ブラウザから「http://127.0.0.1:8000/admin/」にアクセスすると管理画面が表示され、そこに今作成したモデル「Table」が表示されます。

Djangoのdjango.contrib.authを使ってAdminLTEのログイン画面にてユーザ認証

本稿はサーバサイドDjangoとクライアントサイドAdminLTEという環境でログイン画面から初期画面を表示するための設定方法を記載しています。
ログアウト機能も実装しています。
基本的に最低限の設定で済むよう、Djangoが提供している機能を最大限活用しているつもりです。
Djangoはインストール済み、AdminLTEはダウンロード済み(/path/to/AdminLTE)であることを前提としています。

バージョン

  • OS: CentOS 7.3
  • Python: 3.5.1
  • Django: 1.10.4
  • AdminLTE: 2.3.7

Djangoプロジェクト作成

$ django-admin startproject mysite

$ cd mysite/

Djangoプロジェクトファイルの編集

mysite/settings.py

ALLOWED_HOSTS = ['127.0.0.1',] # 変更
# ...(中略)...
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates'),], # 変更
'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',
],
},
},
]
# ...(中略)...
# 以下を追記
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]

LOGIN_URL = '/login/'
LOGIN_REDIRECT_URL = '/'

mysite/views.py

# 以下を作成
from django.shortcuts import render
from django.http import HttpResponse
from django.conf import settings
from django.contrib.auth.decorators import login_required

@login_required
def index(request):
return render(request, 'index.html')

mysite/urls.py

from django.conf.urls import url
from django.contrib import admin
from . import views # 追記
from django.contrib.auth import views as auth_views # 追記

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.index, name='index'), # 追記
url(r'^login/', auth_views.login, { 'template_name': 'login.html' }, name='login'), # 追記
url(r'^logout/', auth_views.logout_then_login, name='logout'), # 追記
]

adminユーザ作成

$ python manage.py createsuperuser
Username (leave blank to use 'username'): admin
Email address:
Password:
Password (again):
Superuser created successfully.

AdminLTEのファイル配置

$ mkdir templates
$ mkdir static
$ cp /path/to/AdminLTE/pages/examples/login.html templates/
$ cp /path/to/AdminLTE/pages/examples/blank.html templates/index.html
$ cp /path/to/AdminLTE/dist static/
$ cp /path/to/AdminLTE/bootstrap static/
$ cp /path/to/AdminLTE/plugins static/

HTMLファイルの編集

template/login.html

{% load static %} <!-- 追記 -->
<!DOCTYPE html>

<!-- 以下、変更箇所 -->
<!-- Bootstrap 3.3.6 -->
<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
<!-- Theme style -->
<link rel="stylesheet" href="{% static 'dist/css/AdminLTE.min.css' %}">
<!-- iCheck -->
<link rel="stylesheet" href="{% static 'plugins/iCheck/square/blue.css' %}">

<div class="login-box-body">
{% if form.errors %} <!-- 追記 -->
<p class="login-box-msg bg-red">Your username and password didn't match. Please try again.</p> <!-- 追記 -->
{% else %} <!-- 追記 -->
<p class="login-box-msg">Sign in to start your session</p>
{% endif %} <!-- 追記 -->

<form action="{% url 'login' %}" method="post">
{% csrf_token %} <!-- 追記 -->
<input type="text" class="form-control" name="username" placeholder="Username">
<input type="password" class="form-control" name="password" placeholder="Password">

<!-- jQuery 2.2.3 -->
<script src="{% static 'plugins/jQuery/jquery-2.2.3.min.js' %}"></script>
<!-- Bootstrap 3.3.6 -->
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
<!-- iCheck -->
<script src="{% static 'plugins/iCheck/icheck.min.js' %}"></script>

template/index.html

{% load static %} <!-- 追記 -->
<!DOCTYPE html>

<!-- 以下、変更箇所 -->
<!-- Bootstrap 3.3.6 -->
<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
<!-- Theme style -->
<link rel="stylesheet" href="{% static 'dist/css/AdminLTE.min.css' %}">
<!-- AdminLTE Skins. Choose a skin from the css/skins
folder instead of downloading all of them to reduce the load. -->
<link rel="stylesheet" href="{% static 'dist/css/skins/_all-skins.min.css' %}">

<img src="{% static 'dist/img/user2-160x160.jpg' %}" class="img-circle" alt="User Image">
<img src="{% static 'dist/img/user2-160x160.jpg' %}" class="user-image" alt="User Image">
<img src="{% static 'dist/img/user2-160x160.jpg' %}" class="img-circle" alt="User Image">

<a href="{% url 'logout' %}" class="btn btn-default btn-flat">Sign out</a>

<img src="{% static 'dist/img/user2-160x160.jpg' %}" class="img-circle" alt="User Image">

<!-- jQuery 2.2.3 -->
<script src="{% static 'plugins/jQuery/jquery-2.2.3.min.js' %}"></script>
<!-- Bootstrap 3.3.6 -->
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
<!-- SlimScroll -->
<script src="{% static 'plugins/slimScroll/jquery.slimscroll.min.js' %}"></script>
<!-- FastClick -->
<script src="{% static 'plugins/fastclick/fastclick.js' %}"></script>
<!-- AdminLTE App -->
<script src="{% static 'dist/js/app.min.js' %}"></script>

ファイル構成

mysite/
| mysite/
| | __pycache__/
| | __init__.py
| | settings.py
| | urls.py
| | views.py
| | wsgi.py
| static/
| | bootstrap/
| | dist/
| | plugins/
| templates/
| | index.html
| | login.html
| manage.py
| db.sqlite3

実行と確認

$ python manage.py runserver 0.0.0.0:8000

ブラウザから「http://127.0.0.1:8000」にアクセスするとログイン画面が出てきます。
ユーザ名「admin」と設定したパスワードを入力すると初期画面が出てきます。
初期画面から「Sign out」をクリックするとログアウトしてログイン画面に戻ります。

Djangoでサンプルページ作成

環境

  • ホスト
    • OS: Windows 10
    • 仮想化ソフト: Vagrant (VirtualBoxを使用)
  • ゲスト
    • OS: CentOS 7.1
    • IPアドレス(プライベートネットワーク): 192.168.33.10
  • 使用するソフトウェアのバージョン(本稿でインストール方法を記載しています)
    • Python: 3.5.1
    • Django: 1.10.4

Python3インストール

こちらのサイトを参考にさせていただきました。

$ sudo yum install -y gcc zlib-devel bzip2 bzip2-devel readline readline-devel sqlite sqlite-devel openssl openssl-devel git

$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv

$ vi ~/.bash_profile
# 以下を追加
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

$ source .bash_profile

$ pyenv install 3.5.1

$ python --version
Python 2.7.5

$ pyenv versions
* system (set by /home/vagrant/.pyenv/version)
3.5.1

$ pyenv global 3.5.1

$ pyenv rehash

$ python --version
Python 3.5.1

$ pyenv versions
system
* 3.5.1 (set by /home/vagrant/.pyenv/version)

Djangoをインストール

$ sudo yum install -y python-pip

$ pip install django

初期ページ表示

$ django-admin startproject mysite

$ cd mysite/

$ vi mysite/settings.py
ALLOWED_HOSTS = ['192.168.33.10',] # 変更

$ python manage.py runserver 0.0.0.0:8000

ブラウザから「192.168.33.10:8000」にアクセスすると下の画像のようなページが表示されます。
initial-page

サンプルページ作成(HTML, CSS, Javascript使用)

$ vi mysite/urls.py
from django.conf.urls import url
from django.contrib import admin
from . import views # 追記

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.index, name='index'), # 追記
]

$ vi mysite/views.py
# 以下を作成
from django.shortcuts import render
from django.http import HttpResponse

def index(request):
return render(request, 'index.html')

$ vi mysite/settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates'),], # 変更
'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',
],
},
},
]

# 以下を追記
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]

$ mkdir templates

$ mkdir static

$ mkdir static/css

$ mkdir static/js

$ vi templates/index.html
# 以下を作成
{% load static %}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Django test page</title>
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<script type="text/javascript" src="{% static 'js/sample.js' %}"></script>
</head>
<body>
<h1 id="title">Django test page</h1>
<button type="button" id="button">Click here</button>
</body>
</html>

$ vi static/css/style.css
# 以下を作成
@charset "UTF-8";

body {
text-align: center;
}

$ vi static/js/sample.js
# 以下を作成
window.addEventListener('load',
function (event) {
document.getElementById('button').addEventListener('click',
function() {
alert('Hello');
}
, false);
}
, false);

$ python manage.py runserver 0.0.0.0:8000

再度、ブラウザから「192.168.33.10:8000」にアクセスすると下の画像のようなページが表示されます。
django-test-page