models.py
models.py
# Create your models here.
from django.db import models
import datetime
JST = datetime.timezone(datetime.timedelta(hours=9))
# Create your models here.
class SampleListModel(models.Model):
title = models.CharField('タイトル',max_length=50)
text = models.TextField('本文')
url = models.URLField('URL', blank=True)
created_at = models.DateTimeField('作成日', default=datetime.datetime.now(tz=JST))
def __str__(self):
return self.title
class SampleDetailModel(models.Model):
name = models.CharField('名前',max_length=256)
feature = models.TextField('特徴')
list = models.ForeignKey(SampleListModel, on_delete=models.CASCADE, related_name='related_list')
def __str__(self):
return self.name
forms.py
forms.py
from .models import SampleListModel, SampleDetailModel
from django.db import models
from django import forms
class SampleListForm(forms.ModelForm):
class Meta:
model = SampleListModel
fields = "__all__"
def __init__(self, *args, **kwargs):
for field in self.base_fields.values():
field.widget.attrs["class"]="form-control"
super().__init__(*args, **kwargs)
class SampleDetailForm(forms.ModelForm):
class Meta:
model = SampleDetailModel
fields = "__all__"
def __init__(self, *args, **kwargs):
for field in self.base_fields.values():
field.widget.attrs["class"]="form-control"
super().__init__(*args, **kwargs)
views.py
views.py
from django.shortcuts import render, get_object_or_404
from django.views.generic import CreateView, ListView, DetailView
from .models import SampleListModel, SampleDetailModel
from .forms import SampleListForm, SampleDetailForm
from django.urls import reverse, reverse_lazy
# Create your views here.
class SampleListCreate(CreateView):
template_name = 'app/list_create.html'
form_class = SampleListForm
success_url = reverse_lazy('app:app/list')
class SampleDetailCreate(CreateView):
template_name = 'app/detail_create.html'
form_class = SampleDetailForm
success_url = reverse_lazy('app:app/list')
class SampleList(ListView):
model = SampleListModel
context_object_name = "sample_list"
template_name = 'app/list.html'
class SampleDetail(DetailView):
model = SampleListModel
context_object_name = "sample_detail"
template_name = "app/detail.html"
pj/urls.py
pj/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('app.urls')),
]
app/urls.py
app/urls.py
from django.contrib import admin
from django.urls import path
from . import views
app_name = 'app'
urlpatterns = [
path('', views.SampleList.as_view(), name='app/list'),
path('detail/<int:pk>', views.SampleDetail.as_view(), name='app/detail'),
path('list_create', views.SampleListCreate.as_view(), name='app/list_create'),
path('detail_create', views.SampleDetailCreate.as_view(), name='app/detail_create'),
]
settings.py
settings.py
"""
Django settings for pj project.
Generated by 'django-admin startproject' using Django 3.2.6.
For more information on this file, see
![]()
DjangoThe web framework for perfectionists with deadlines.
For the full list of settings and their values, see
![]()
DjangoThe web framework for perfectionists with deadlines.
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-!f$ze!g_kk^w09n61tf$9h5+yrpbo7mccflq#jmb@1b1^$99eu'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'pj.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [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',
],
},
},
]
WSGI_APPLICATION = 'pj.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
import os
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static/"),
)
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
pj/templates/app/base.html
pj/templates/app/base.html
{% load static %}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Python Django CreateView, ListView, DetailView</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<link rel="stylesheet" href="{% static 'app/style.css' %}">
</head>
<body>
<header class="page-header wrapper">
<h1><a href="/"><img class="logo" src="images/logo_zeroterasu.png" alt="ZeroTerasuウェブサイト ホーム"><span> ZeroTerasu WebSite</span></a></h1>
<nav class="page-nav">
<ul class="main-nav">
<li><a href="about.html">プロフィール</a></li>
<li><a href="works.html">制作実績</a></li>
<li><a href="https://zeroterasu.com/blog/">ブログ</a></li>
<li><a href="contact.php">お問い合わせ</a></li>
</ul>
</nav>
</header>
{% block main %}
{% endblock %}
<footer>
<div class="wrapper">
<p><small>© 2021 ZeroTerasu</small></p>
<a href="privacy_policy">プライバシーポリシー</a>
</div>
</footer>
</body>
</html>
pj/templates/app/list_create.html
pj/templates/app/list_create.html
{% extends 'app/base.html' %}
{% block main %}
<div class="container my-3">
<div class="text-center my-3">
<h2>新しいリストを作成</h2>
</div>
<form method="POST"> {% csrf_token %}
{{ form.as_p }}
<button class="btn btn-primary form-control" type="submit">登録</button>
</form>
<a href="{% url 'app:app/list' %}">リスト一覧ページ</a><br>
<a href="{% url 'app:app/detail_create' %}">詳細作成ページ</a><br>
</div>
{% endblock %}
pj/templates/app/detail_create.html
pj/templates/app/detail_create.html
{% extends 'app/base.html' %}
{% block main %}
<div class="container my-3">
<div class="text-center my-3">
<h2>新しい詳細を作成</h2>
</div>
<form method="POST"> {% csrf_token %}
{{ form.as_p }}
<button class="btn btn-primary form-control" type="submit">登録</button>
</form>
<a href="{% url 'app:app/list' %}">リスト一覧ページ</a><br>
<a href="{% url 'app:app/list_create' %}">リスト作成ページ</a><br>
</div>
{% endblock %}
pj/templates/app/list.html
pj/templates/app/list.html
{% extends 'app/base.html' %}
{% block main %}
<div class="wrapper">
<h2>リスト一覧</h2>
<table class="table">
<thead>
<tr>
<th>リスト名</th>
<th></th>
</tr>
</thead>
<tbody>
{% for sample in sample_list %}
<tr>
<td>{{ sample.title }}</td>
<td><a href="detail/{{ sample.id }}">詳細</a></td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{% url 'app:app/list_create' %}">リスト作成ページ</a><br>
<a href="{% url 'app:app/detail_create' %}">詳細作成ページ</a><br>
</div>
{% endblock %}
pj/templates/app/detail.html
pj/templates/app/detail.html
{% extends 'app/base.html' %}
{% block main %}
<div class="wrapper">
<h2>詳細ページ</h2>
<h2>リスト詳細</h2>
<table class="table">
<thead>
<tr>
<th scope="col">リスト名</th>
<th scope="col">本文</th>
<th scope="col">URL</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ sample_detail.title }}</td>
<td>{{ sample_detail.text }}</td>
<td>{{ sample_detail.url }}</td>
</tr>
<tbody>
</table>
<h3>詳細情報</h3><br>
<table class="table">
<thead>
<tr>
<th scope="col">name</th>
<th scope="col">feature</th>
</tr>
</thead>
<tbody>
{% for detail in sample_detail.related_list.all %}
<tr>
<td>{{ detail.name }}</td>
<td>{{ detail.feature }}</td>
</tr>
{% endfor %}
<tbody>
</table>
<br>
<a href="{% url 'app:app/list' %}">リスト一覧ページ</a><br>
<a href="{% url 'app:app/list_create' %}">リスト作成ページ</a><br>
<a href="{% url 'app:app/detail_create' %}">詳細作成ページ</a><br>
</div>
{% endblock %}
admin.py
admin.py
from django.contrib import admin
from .models import *
admin.site.register(SampleListModel)
admin.site.register(SampleDetailModel)
コメント