Djangoの呪文書

# まえがき
Djangoの学習にあたって、ルール的に記載が必要なもの、記法などの初心者特有の呪文がある。他の言語の呪文と混ざってしまったり、似た種類の呪文を採用してしまうなどのミスを防ぐために呪文を自分用のドキュメントとして記載する。

## 環境
- windows11 64bit
- VScode
- python v3.9.6 64bit
- django v4.0.1

## 構成
### プロジェクト作成
```
django-admin startproject hogehoge
```
### アプリ作成
```
python manage.py startapp hogehoge
```

### データベースの作成
```
python manage.py migrate
```

### ユーザの作成
```
python manage.py createsuperuser
```

### サーバーの開始
```
python manage.py runserver 
```

### その他
```
mkdir templates
mkdir static
mkdir media
touch ./hogehogeapp/urls.py
touch ./templates/base.html
touch ./templates/hoge.html
touch ./static/style.css
```

### 構成
```
- hogehogeproject
　- hogehogeproject
　- hogehogeapp
　- templates
　- static
　- media
　- db.sqlite3
　- manage.py
```

## コード
### hogehogeproject/setting.py
```python
# ベースのパスの追加
BASE_DIR = Path(__file__).resolve().parent.parent

# アプリケーションの組み込み
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'hogehogeapp',
]

# テンプレートの指定
TEMPLATES = [
    {
        'BACKEND': ...,
        'DIRS': [BASE_DIR, 'templates'],
        'APP_DIRS': True,
        'OPTIONS': {
            ...,
        },
    },
]

# cssの指定
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/

STATIC_URL = 'static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

# 画像の指定
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # 画像を保存するURL

MEDIA_URL = '/media/' #画像を表示するURL

```
### templates/base.html
[ここから](https://getbootstrap.jp/docs/5.0/getting-started/introduction/)スターターテンプレートをコピペして、blockを作成する
```html
<!doctype html>
<html lang="ja">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

    {% block customcss %}
    {% endblock customcss %}

    <title>Hello, world!</title>
  </head>
  <body>
    {% block header %}
    {% endblock header %}

    {% block content %}
    {% endblock content %}

    <!-- Optional JavaScript; choose one of the two! -->

    <!-- Option 1: Bootstrap Bundle with Popper -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

    <!-- Option 2: Separate Popper and Bootstrap JS -->
    <!--
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>
    -->
  </body>
</html>


```
### templates/hoge.html
```html
{% extends 'base.html' %}
{% load static %}

{% block customcss %}
<link rel='stylesheet' type='text/css' href="{% static 'style.css' %}">
{% endblock customcss %}

{% block header %}
{% endblock header %}

{% block content %}
{% endblock content %}
```
#### Tips
- フォームを使用する場合はトークンを付与する
```html
<form method="POST" action="">{% csrf_token %}
</form>
```

### hogehogeproject/urls.py
```python
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('hogehogeapp.urls')),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
```
### hogehogeapp/models
```python
from django.db import models

class HogeModel:
    title = models.CharField(max_length=100)
    txt = models.TextField()
    no = models.IntegerField()
    duedate = models.DateField()
    def __str__(self):
        return self.title
```

### hogehogeapp/views.py
```python
# import
from django.views.generic import ListView, DetailView, CreateView, DeleteView, UpdateView
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.urls import reverse_lazy

# 関数型
def hogefunc(request):
    return HttpResponse("Hello, World!")

def hoge1func(request):
    return render(request, 'hogehoge.html')

@login_required
def hoge2func(request):
    return redirect('hoge2')

# クラス型
class HogeList(ListView):
    template_name = 'hoge.html'
    model = HogeModel

class HogeDetail(DetailView):
    template_name = 'hoge.html'
    model = HogeModel

class HogeCreate(CreateView):
    template_name = 'hoge.html'
    model = HogeModel
    fields = ('title', 'txt', 'no', 'duedate')
    success_url = reverse_lazy('hoge')

class HogeDelete(DeleteView):
    template_name = 'hoge.html'
    model = HogeModel
    success_url = reverse_lazy('hoge')

class HogeUpdate(UpdateView):
    template_name = 'hoge.html'
    model = HogeModel
    fields = ('title', 'txt', 'no', 'duedate')
    success_url = reverse_lazy('hoge')
```

#### Tips
- [HttpResponse](https://docs.djangoproject.com/ja/4.1/ref/request-response/#django.http.HttpResponse)/ [render](https://docs.djangoproject.com/ja/4.1/topics/http/shortcuts/#django.shortcuts.render) / [redirect](https://docs.djangoproject.com/ja/4.1/topics/http/shortcuts/#django.shortcuts.redirect)の違い
[こちら](https://kuma-server.com/django-render-redirect-httpresponse/#toc4)の記事がわかりやすかったです。
- **redirect**や**reverse_lazy**で、hogehogeapp/urls.pyで定義した**name**を指定

### hogehogeapp/urls.py
```python
from django.urls import path
from .views import hogefunc, hoge1func, hoge2func, HogeList, HogeDetail, HogeCreate, HogeDelete, HogeUpdate

urlpatterns = [
    path('hoge/', hogefunc, name='hoge'),
    path('hoge1/', hoge1func, name='hoge1'),
    path('hoge2/', hoge2func, name='hoge2'),
    path('list/', HogeList.as_view(), name='list'),
    path('detail/<int:pk>', HogeDetail.as_view(), name='detail'),
    path('create', HogeCreate.as_view(), name='create'),
    path('delete/<int:pk>', HogeDelete.as_view(), name='delete'),
    path('update/<int:pk>', HogeUpdate.as_view(), name='update'),
]

```

#### Tips
- クラスベースの場合は、クラス名＋**as_view()**をつける

# あとがき
知識や理解が浅かったり、説明が足りてなかったり、本来はもっと注意すべきこと、などがあると思うので、学習に合わせて内容を更新していきます。

# 参考
- [Django ドキュメント](https://docs.djangoproject.com/ja/4.1/)
- [Bootstrap](https://getbootstrap.jp/)
- [くまのブログ - 【Django】render / redirect / HttpResponseなどの違い](https://kuma-server.com/django-render-redirect-httpresponse/#toc4)

# 更新履歴
- 2023/01/11: 記事公開