BBS

## 掲示板作成

### プロジェクト作成

現在の場所を確認(最後がdjango_appならOK)
/Users/XXXXXXX/Dev/vantan/django_app

「**python manage.py startapp ○○○○**」(○○の中身はアプリ名)とする

### 確認
bbsフォルダがdjango_app直下にあればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/bb05df88-660d-d255-facd-8522fbabf510.png)

### Hello World

bbs > views.py
```views.py
from django.shortcuts import render

from django.http import HttpResponse

#def関数を使って表示させる内容を書く

def index(request):

    return HttpResponse('Hello World')
```
ルーティングの設定
myappのurls.pyの編集
mywpp > urls.py
```urls.py
from django.contrib import admin

from django.urls import include, path


urlpatterns = [

    path('bbs/', include('bbs.urls')),

    path('admin/', admin.site.urls),
]
```

### bbsフォルダにurls.pyファイルを作成

作成したurls.pyに以下を記述
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/589c6315-eeb6-c283-7b2d-c8698f9d3c8d.png)

bbs > urls.py
```urls.py
from django.urls import path

from . import views


urlpatterns = [

  path('', views.index, name='index'),

]
```
### bbsアプリケーションを登録
myappのsettings.pyを編集
myapp > settings.py
```settings.py
INSTALLED_APPS = [

    'bbs.apps.BbsConfig',

    'django.contrib.admin',

    'django.contrib.auth',................
```
### サーバー起動
「**python manage.py runserver**」をターミナルに入力する
起動しない場合は文頭を「python3」 で入力する
![スクリーンショット 2024-12-19 13.59.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/1e123930-9108-a749-f8b9-2041d72334ea.png)

ブラウザを開いて
127.0.0.1:8000
の末尾に「/bbs」を追加

### 開いたブラウザに「Hello World」が表示されると成功


# テンプレートの追加
## 呼び出すファイルを指定
### bbs/views.py を編集
bbs > views.py
```views.py
def index(request):

    return render(request, 'bbs/index.html')
```
render関数：データとテンプレートファイルを指定すると、Webページを返してくれる

## テンプレート作成
bbsフォルダにtemplatesフォルダを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/806f5340-d910-f7f7-198e-ebb5df79d26f.png)
templatesの中にbbsフォルダを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/67c7b9bb-6231-8eab-f3cf-d3522aaa1726.png)
bbs/templates/bbsフォルダにindex.htmlファイルを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/cc404c09-8e07-e4a5-d61e-8f05ebf857d5.png)

## index.html編集

<今回は静的なコンテンツを表示>
templates > bbs > index.html
```index.html
<!DOCTYPE html>

<html lang="ja">

<head>

  <meta charset="UTF-8">

  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>bbs</title>

</head>

<body>

  <h1>Hello Django</h1>

</body>

</html>
```

## 確認

必要があれば
**python manage.py runserver**

もしエラー（Error: That port is already in use.）が出た場合
```
kill `lsof -ti tcp:8000`
```
を入力した後
**python manage.py runserver**

先ほどサーバー起動したリンク
127.0.0.1:8000/bbs/にアクセス

Hello Djangoが大きな文字で表示されていればOK

# テンプレートにデータを渡す
## 辞書型でデータを渡す
### bbs/views.py
bbs > views.py
```views.py
def index(request):

    context = {'message': "Welcome my BBS"}

    return render(request, 'bbs/index.html', context)
```

### テンプレートで変数の表示
jinja2では{{ 変数名 }} とすることで値を表示できる
例
```
<h1>{{ 変数 }}<h1>
```
### index.html編集
templates > bbs > index.html
```index.html
<body>

  <h1>Hello Django</h1>

  <p>{{ message }}</p>

</body>
```

## データの追加
bbs > views.py
```views.py
def index(request):

    context = {'message': "Welcome my BBS",

                'members':["AAAさん", "BBBさん", "CCCさん"]

                }

    return render(request, 'bbs/index.html', context)
```

### テンプレートで呼び出し
{% ○○○ %}とすることで、テンプレートエンジン内でコードや制御フローを記述できる
これは通常、制御文やループ、条件分岐などのテンプレートロジックを埋め込むために使用される

### index.html編集
templates > bbs > index.html 
```index.html
<body>

  <h1>Hello Django</h1>

  <p>{{ message }}</p>


  {% for member in members %}

    <p>{{ member }}は一年生です。</p>

  {% endfor %}

</body>
```

# Model

Modelは、データベースのテーブルに対応するPythonのクラス
Modelを作成することで、Pythonでデータベースのテーブル定義、データの追加・更新・削除、データを取得などができる

### ORマッパー
オブジェクト指向プログラミングとリレーショナルデータベースの間のデータのマッピングを指します。ORマッパーは、プログラム内のオブジェクトとデータベースのテーブルとの間でデータのやり取りを簡素化し、効率化するためもの

### bbs/models.py編集
bbs > models.py
```models.py
from django.db import models


class Article(models.Model):

    content = models.CharField(max_length=200)


    def __str__(self):

        return self.content
```
### マイグレーション（migration）
データベーススキーマ（テーブル、フィールド、制約など）を変更し、その変更をデータベースに適用するための仕組み。マイグレーションは、Djangoアプリケーションのモデルに変更を加えたり、新しいモデルを追加したりした場合に、データベーススキーマを同期させることができる


### マイグレーションファイルの作成
ターミナルで
**python manage.py makemigrations bbs**
![media.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/adc2847a-91c4-7ebc-ae51-9bfb6e4bc9b0.png)

### DBに反映
**python manage.py migrate**
![media (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/055e8373-a983-47e1-53f8-b50667148a3e.png)
### phpmyadminで確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/6f86c918-759f-7ccf-53d0-798a03e4982e.png)

# 管理サイト
Djangoの管理サイト（Admin Site）は、Djangoが提供する強力な管理ツール
これを使用することで、データベース内のデータを操作したり管理したりするためのWebベースのインターフェースを使用できる

管理サイトを利用することで、データベースの管理作業やコンテンツの編集を非常に効率的に行うことができる
### superuserの作成
ターミナルで
**django_app/ % python manage.py createsuperuser**

### username
Username (leave blank to use 'shibaikekengo'): admin

### email
Email address: admin@admin.com

### password（root）
Password: 

Password (again): 

This password is too short. It must contain at least 8 characters.

This password is too common.

Bypass password validation and create user anyway? [y/N]: y

Superuser created successfully.

### サーバー起動
**python manage.py runserver**

### URL変更
http://127.0.0.1:8000/admin
(127.0.0.1:8000の末尾に「/admin」を追加)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/576b724d-392f-260c-4083-5eff7e0218e2.png)

### 管理サイトにログイン
Username:admin
Password:root
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/2ad4c062-8331-b7be-0c9e-6473ed8cbc2b.png)

## Articleモデルを操作できるようにする
### bbs/admin.pyを編集
bbs > admin.py
```
from django.contrib import admin

from .models import Article

admin.site.register(Article)
```
管理サイトをリロード ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/6f3e2a6f-0c7a-6376-4266-c3f5bb5283c5.png)

### Articlesテーブルにデータを追加
+Add をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/03da7d47-a482-2297-6f55-4adfb381d195.png)

Contentにテキストを入力
下のSAVEボタンを押下

３つ登録しましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/4506e657-d49e-15e7-5667-e191c31d5ce5.png)

Articlesテーブルのcontentカラムにデータが３つ格納されていればOK

# Modelデータの表示
### bbsの表示
**python manage.py runserver**
↓
ブラウザ：http://127.0.0.1:8000/bbs/

## データの取得と表示
### Views.pyでModelからデータを取り出す
bbs > views.py
```views.py
from django.shortcuts import render

from django.http import HttpResponse

from .models import Article


def index(request):

    articles = Article.objects.all()

    context = {'message': "Welcome my BBS",

                'articles': articles,

                }

    return render(request, 'bbs/index.html', context)
```

### テンプレートで表示
↓ templates > bbs > index.html
```index.html
<body>

  <h1>Hello Django</h1>

  <p>{{ message }}</p>


  {% for article in articles %}

    <p>{{ article }}</p>

  {% endfor %}

</body>
```
↓ ブラウザで確認（要更新）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/2633ab1d-3960-761c-c437-73e14c678f51.png)

# データの詳細表示
データを個別のページで表示します

ルーティング、モデル、ビューの理解を深めましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/03c56e2d-cf25-985f-19a4-8c7b74582e32.png)

### 個別ページ
URLにidをつけて各投稿を1ページで表示
localhost/bbs/id

### urls.py編集
```urls.py
from django.urls import path

from . import views


app_name = 'bbs'


urlpatterns = [

  path('', views.index, name='index'),

  path('<int:id>', views.detail, name='detail'),

]
```

## 動作確認
### views.py編集
bbs > views.py
```views.py
from django.shortcuts import render,get_object_or_404

from django.http import HttpResponse

from .models import Article


def index(request):

    articles = Article.objects.all()

    context = {'message': "Welcome my BBS",

                'articles': articles,

                }

    return render(request, 'bbs/index.html', context)


def detail(request, id):

    article = get_object_or_404(Article, pk=id)

    return HttpResponse(article)
```

### 動作確認
http://127.0.0.1:8000/bbs/1
http://127.0.0.1:8000/bbs/2
http://127.0.0.1:8000/bbs/4

## テンプレートから表示
### views.py編集
bbs > views.py
```views.py
def detail(request, id):

    article = get_object_or_404(Article, pk=id)

    context = {

        'message': 'ページID:'+ str(id),

        'article': article,

    }

    return render(request, 'bbs/detail.html', context)
```

## テンプレート作成
### detail.html作成 
templates > bbs > detail.html
```detail.html
<!DOCTYPE html>

<html lang="ja">

<head>

  <meta charset="UTF-8">

  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>bbs - {{ article.id }}</title>

</head>

<body>

  <h1>Hello Django</h1>

  <p>{{ message }}</p>


  <p>{{ article.content }}</p>

  <p><a href='{% url "bbs:index" %}'>一覧に戻る</a></p>

</body>

</html>
```

### 確認
http://127.0.0.1:8000/bbs/1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/1227983f-c1f3-5703-5269-0cce3722f687.png)

## 一覧表示画面からも各ページに遷移
### index.html編集
templates > bbs > index.html
```index.html
<body>

  <h1>Hello Django</h1>

  <p>{{ message }}</p>


  {% for article in articles %}

    <p>{{ article }}

      <a href='{% url "bbs:detail" article.id %}'>詳細</a>

    </p>

  {% endfor %}

</body>
```
## 確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965340/96b483e8-1989-2697-1544-7723618b2925.png)

Djangoプロジェクトやアプリケーション内のコードを実行し、データベースへのアクセスや操作、モデルのテスト、開発中の機能のテストなどを行うことができます。

### 起動方法
プロジェクトフォルダ（django_app/）で

**python manage.py shell**

### print()
print('Hello')

### 終了方法
contorl + D ⇨ Enter

## DB操作
### Djangoシェルの起動
プロジェクトフォルダ（django_app/）で

**python manage.py shell**

### インポート
**from bbs.models import Article**

### 全件取得
**Article.objects.all()**

### 個別に取得
idが1のデータを取得し、article変数に格納

**article = Article.objects.get(pk=1)**

### 呼び出し
（contentはカラム名）

**article.content**

### データの追加
**article = Article(content='お腹いっぱいです')**
**article.save()**

### 確認
**Article.objects.all()**

### データの編集
編集したいデータを取得

**article = Article.objects.get(pk=4)**

### 確認
**article.content**

### 編集
**article.content = '楽しかったです'**

**article.save()**

### 確認
**Article.objects.all()**

### 削除
「楽しかったです」を削除

**article.delete()**

### 確認
**Article.objects.all()**

# Migration(マイグレーション)

Djangoにおけるマイグレーションは、データベーススキーマの変更を管理し、実際のデータベースに反映させるための仕組み

データベーススキーマとは、データベース内のテーブル、カラム、インデックスなどの構造を指す

## 手順
### モデルの変更
models.py ファイルで、データベーステーブルの構造に変更を加える操作（新しいフィールドの追加、既存フィールドの変更、テーブルの削除など）を行う


### bbs/models.py
（user_nameを追加）
```models.py
class Article(models.Model):

    

    content = models.CharField(max_length=200)

    user_name = models.CharField(max_length=100)
```

### マイグレーションの作成
makemigrations コマンドを実行して、モデルの変更内容をマイグレーションファイルとして記録
（migrationsフォルダに新しいファイルが作られる）

### ターミナル
django_app/ フォルダで
**python manage.py makemigrations bbs**

ターミナルにメッセージが出るので2を入力してEnter

bbs > models.py
（user_nameでnullを許容する）
```models.py
class Article(models.Model):
    content = models.CharField(max_length=200)

    user_name = models.CharField(max_length=100, null=True)
```
### ターミナル
django_app/ フォルダで
**python manage.py makemigrations bbs**

### マイグレーションの適用
migrate コマンドを実行して、マイグレーションファイルに記録された変更を実際のデータベースに適用
これにより、データベースの構造が変更内容に合わせて更新される

### ターミナル
**python manage.py migrate**