36歳がDjangoでランチマップのコードをまとめた
今回は以下で作成した、ランチマップアプリ作成のコードをすべてまとめました。
このコードをコピーすれば同じものが出来上がります。
【環境】
以下の環境で構築しています。
OS:Ubuntu20.04
python -V
Python 3.8.2
apache2 -version
Server version: Apache/2.4.41 (Ubuntu)
Server built: 2020-04-13T17:19:17
mysql --version
mysql Ver 8.0.20-0ubuntu0.20.04.1 for Linux on x86_64 ((Ubuntu))
pypmyadmin
バージョン情報: 4.9.5deb2
Ubuntu20.04に各環境を構築する場合は、以下ページを参照ください。
【画面サンプル】
最終的に以下のような画面が出来上がります。
【各コード】
このコードでは、プロジェクト名「myapp」、アプリケーション名「lunchmap」として記載しています。
もし、別名にしたい場合は、適宜コードを読み替えてください。
ファイル:myapp>lunchmap>admin.py
コード:
from django.contrib import admin
from .models import Category,Shop
admin.site.register(Category)
admin.site.register(Shop)
ファイル:myapp>lunchmap>models.py
コード:
from django.db import models
from django.urls import reverse
class Category(models.Model):
name = models.CharField(max_length=255)
author = models.ForeignKey(
'auth.User',
on_delete=models.CASCADE,
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
class Shop(models.Model):
name = models.CharField(max_length=255)
address = models.CharField(max_length=255)
author = models.ForeignKey(
'auth.User',
on_delete=models.CASCADE,
)
category = models.ForeignKey(
Category,
on_delete=models.PROTECT,
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('lunchmap:detail', kwargs={'pk': self.pk})
ファイル:myapp>lunchmap>urls.py
コード:
from django.urls import path
from . import views
app_name = 'lunchmap'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
path('create/', views.CreateView.as_view(), name='create'),
path('<int:pk>/update/', views.UpdateView.as_view(), name='update'),
path('<int:pk>/delete/', views.DeleteView.as_view(), name='delete'),
]
ファイル:myapp>lunchmap>views.py
コード:
from django.urls import reverse_lazy
from django.views import generic
from .models import Category, Shop
class IndexView(generic.ListView):
model = Shop
class DetailView(generic.DetailView):
model = Shop
class CreateView(generic.edit.CreateView):
model = Shop
fields = '__all__'
class UpdateView(generic.edit.UpdateView):
model = Shop
fields = '__all__'
class DeleteView(generic.edit.DeleteView):
model = Shop
success_url = reverse_lazy('lunchmap:index')
ファイル:myapp>lunchmap>templates>lunchmap>base.html
コード:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no'>
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css'>
<style>body {padding-top:80px;}</style>
<title>Lunchmap</title>
</head>
<body>
<nav class='navbar vabar-expand -sm navbar-dark bg-dark fixed-top'>
<a class='navbar-brand' href='{% url "lunchmap:index" %}'>ランチマップ</a>
</nav>
<div class='container'>
{% block content %}
{% endblock %}
</div>
</body>
</html>
ファイル:myapp>lunchmap>templates>lunchmap>shop_list.html
コード:
{% extends './base.html' %}
{% block content %}
<h1>お店一覧</h1>
<table class='table table-striped table-hover'>
<tr>
<th>カテゴリ</th><th>店名</th><th>住所</th>
</tr>
{% for shop in object_list%}
<tr>
<td>{{ shop.category.name }}</td>
<td><a href='{% url "lunchmap:detail" shop.pk %}'>{{ shop.name }}</a></td>
<td>{{ shop.address }}</td>
</tr>
{% endfor %}
</table>
<div>
<a href='{% url "lunchmap:create" %}'>新規作成</a>
</div>
{% endblock %}
ファイル:myapp>lunchmap>templates>lunchmap>shop_detail.html
コード:APIキーはご自分のものを利用してください。
APIキーの取得方法
1. Google Developers Consoleにアクセスする
Google Developers Console
https://console.developers.google.com/
2. プロジェクトを作成を選択
3. Google APIが表示されたら、Google Maps APIから「Google Maps Embed API」を選択
4. 「有効にする」をクリック
5. 「認証情報を作成」をクリックして「AIPキー」を選択
6. 表示されたAPIキーを記録する
{% extends './base.html' %}
{% block content %}
<h1>{{ shop.name }}</h1>
<div>
<p>{{ shop.category.name }}</p>
<p>{{ shop.address }}</p>
</div>
<iframe id = 'map'
src='https://www.google.com/maps/embed/v1/place?key=自分のAPIキーを入力&q={{ shop.address }}'
width='100%'
height='320'
frameborder=='0'>
</iframe>
<div>
<a href='{% url "lunchmap:index" %}'>一覧</a>
<a href='{% url "lunchmap:update" shop.pk %}'>編集</a>
<a href='{% url "lunchmap:delete" shop.pk %}'>削除</a>
</div>
{% endblock %}
ファイル:myapp>lunchmap>templates>lunchmap>shop_form.html
コード:
{% extends './base.html' %}
{% block content %}
<h1>お店の情報{{ object|yesno:'更新,作成' }}</h1>
<form action ='' method='post'>{% csrf_token %}
{{ form.as_p }}
<button type='submit' class='submit'>{{ object|yesno:'更新,作成'}}</button>
</form>
<div>
<a href='JavaScript:history.back()'>戻る</a>
</div>
{% endblock %}
ファイル:myapp>lunchmap>templates>lunchmap>shop_confirm_delete.html
コード:
{% extends './base.html' %}
{% block content %}
<h1>お店の情報の削除</h1>
<p>'{{ object.name }}'を削除しますか?</p>
<form action ='' method='post'>{% csrf_token %}
<button type='submit' class='submit delete'>削除する</button>
</form>
<div>
<a href='JavaScript:history.back()'>戻る</a>
</div>
{% endblock %}
ファイル:myapp>myapp>urls.py
コード:
from django.contrib import admin
from django.urls import path, include
from django.views.generic import RedirectView
urlpatterns = [
path('admin/', admin.site.urls),
path('lunchmap/', include('lunchmap.urls')),
path('', RedirectView.as_view(url='/lunchmap/')),
]
ファイル:myapp>myapp>settings.py
コード:該当部分のみ修正
ALLOWED_HOSTS = ['*']
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'lunchmap.apps.LunchmapConfig',
]
DATABASES = {
'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE': 'django.db.backends.mysql',
'NAME': 'lunchmapdb',
'USER': 'testuser',
'PASSWORD': 'testuser',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}