Djangoで簡単なブログサイトを作る流れ

# はじめに
[DjangoBrothers](https://djangobrothers.com)のチュートリアルでDjangoを学んだので、Djangoで簡単なブログサイトを作る流れをまとめてみます。
# Djangoの流れ
## 仮想環境を作りdjangoをインストール
```
$ mkdir DjangoBros
$ cd DjangoBros
DjangoBros $ python3 -m venv djangobros_venv
DjangoBros $ source djangobros_venv/bin/activate
(djangobros_venv) DjangoBros $ pip install --upgrade pip
(djangobros_venv) DjangoBros $ pip install django
(djangorbos_venv) DjangoBros $ deactivate
```

## プロジェクトを作る
```
DjangoBros $ source djangobros_venv/bin/activate
(djangobros_venv) DjangoBros $ django-admin startproject django_blog
(djangobros_venv) DjangoBros $ cd django_blog
(djangobros_venv) django_blog $ python manage.py runserver
```

設定を変える
settings.py

```py

LANGUAGE_CODE = 'ja-JP'
TIME_ZONE = 'Asia/Tokyo'
```
migrateする

```
(djangobros_venv) django_blog $ python manage.py migrate
```
## アプリを作る
```
(djangobros_venv) django_blog $ python manage.py startapp blogs
```


プロジェクトにアプリを登録　
settings.py

```py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blogs',
]
```

templates

```
(djangobros_venv) blogs $ mkdir templates
(djangobros_venv) blogs $ cd templates
(djangobros_venv) templates $ mkdir blogs
(djangobros_venv) templates $ cd blogs
(djangobros_venv) templates $ touch index.html
```

views.py

```py

from django.shortcuts import render

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

django_blogsプロジェクトのurls.py
blogsアプリのurls.pyを読み込むようにする

```py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blogs.urls')),
]
```

blogsアプリのurls.py

```py

from django.urls import path
from . import views

app_name = 'blogs'
urlpatterns = [
    path('', views.index, name='index'),
]
```

## データベースを作る
models.py

```py
from django.db import models

class Blog(models.Model):
    title = models.CharField(blank=False, null=False, max_length=150)
    text = models.TextField(blank=True)
    created_datetime = models.DateTimeField(auto_now_add=True)
    updated_datetime = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title
```
migrate

```
django_blog $ python manage.py makemigrations
django_blog $ python manage.py migrate
```
## adminページを作成
```
django_blog $ python manage.py createsuperuser
```

django/blogs/admin.py

```py

from django.contrib import admin
from .models import Blog

class BlogAdmin(admin.ModelAdmin):
    list_display = ('id', 'title', 'created_datetime', 'updated_datetime')
    list_display_links = ('id', 'title')

admin.site.register(Blog, BlogAdmin)
```
`http://127.0.0.1:8000/admin`にアクセス

## データベースの操作
操作の練習、コマンドの例

```
$ python manage.py shell

 from blogs.models import Blog

 Blog.objects.all()
 Blog.objects.get(id=1)
 Blog.objects.filter(title__contains="Django")
 Blog.objects.order_by('id')
 Blog.objects.order_by('-id')
 Blog.objects.filter(title__contains="Django").order_by('-id')
 
 Blog.objects.create(title="コマンドから作られたブログ", text="createメソッドでブログを作ってみました。")
 
 blog = Blog.objects.get(id=1)
 blog.title
 
 blogs = Blog.objects.all()
 blogs[0].text
```
## クエリセットをHTMLで表示する
views.py

```py

from django.shortcuts import render
from .models import Blog

def index(request):
    blogs = Blog.objects.order_by('-created_datetime')
    return render(request, 'blogs/index.html', {'blogs': blogs})
```

index.html

```html

<h1>ブログサイト</h1>
<p>ここはトップページです。</p>
{% for blog in blogs %}
  {{ blog.title }}
{% endfor %}
```
ちゃんと書くと

```html

<!DOCTYPE html>
<html>
<head>
  <title>ブログ管理サイト</title>
</head>
<body>
  <h1 style="text-align: center;">My Blog</h1>
  <div style="width: 70%;margin: 0px auto;">
    <hr />
    {% for blog in blogs %}
    <div>
      <h3>{{ blog.title }}</h3>
      <div>{{ blog.text | truncatechars:100 }}</div>
    </div>
    <hr />
    {% endfor %}
  </div>
</body>
</html>
```
    
## 詳細ページを作る
詳細ページへのリンクを追加

```html

<!DOCTYPE html>
<html>
<head>
  <title>ブログ管理サイト</title>
</head>
<body>
  <h1 style="text-align: center;">My Blog</h1>
  <div style="width: 70%;margin: 0px auto;">
    <hr />
    {% for blog in blogs %}
    <div>
      <h3>{{ blog.title }}</h3>
      <div>{{ blog.text | truncatechars:100 }}</div>
      <div style="text-align: right;">
        <a href="{% url 'blogs:detail' blog_id=blog.id %}">記事を読む</a>
      </div>
    </div>
    <hr />
    {% endfor %}
  </div>
</body>
</html>
```

urls.py

```py

from django.urls import path
from . import views

app_name = 'blogs'
urlpatterns = [
    path('', views.index, name='index'),
    path('detail/<int:blog_id>/', views.detail, name='detail'),
]
```

views.py

```py
from django.shortcuts import render
from .models import Blog

・・・

def detail(request, blog_id):
    blog = Blog.objects.get(id=blog_id)
    return render(request, 'blogs/detail.html', {'blog': blog})
```

templates/detail.html

```html
<!DOCTYPE html>
<html>
<head>
  <title>ブログアプリ</title>
</head>
<body>
  <h1 style="text-align: center;">{{ blog.title }}</h1>
  <div style="width: 70%;margin: 0px auto;">
    <div>
      <div style="margin: 60px 20px;">
        {{ blog.text }}
      </div>
      <div style="text-align: center; margin-top: 50px">
        <a href="{% url 'blogs:index' %}">トップページに戻る</a>
      </div>
    </div>
  </div>
</body>
</html>
```