はじめに
やったことをまとめると以下3つ
- 1日で出来る!DjangoでCRUDを作るの続き(ソースはここのページのものが基準になってます)
- シーケンスをちゃんと使うようにした
- 連番の取得を、登録されている最大値+1からの脱却
-
FormModel
を少し使えるようにした-
views.py
とtemplates
の連携をTodo
を利用していたが、TodoForm
を使うように修正
-
シーケンスを使ってみた
Djangoで提供してくれているようなのでそちらを使ってみた
[vagrant@localhost mysite]$ sudo pip3 install django-sequences
Collecting django-sequences
Downloading https://files.pythonhosted.org/packages/7a/2d/0c21146f8283ee56b3d920859e55be2550b2c8fb9fb8b6aa9ac2930690ea/django_sequences-2.2-py2.py3-none-any.whl
Installing collected packages: django-sequences
Successfully installed django-sequences-2.2
[vagrant@localhost mysite]$ python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sequences, sessions, todos
Running migrations:
Applying sequences.0001_initial... OK
[vagrant@localhost mysite]$ python3 manage.py shell
Python 3.7.0 (default, Jul 26 2018, 15:06:09)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from sequences import get_next_value
>>> get_next_value('todo_seq')
1
>>> get_next_value('todo_seq')
2
>>> get_next_value('todo_seq_next')
1
>>> get_next_value('todo_seq')
3
これでよしなにsequence
で発番ができたので、シーケンスを使うようにする
todos/views.py
def add(request):
t1 = Todo()
t1 = get_next_value('todo_seq')
t = TodoForm(request.POST, instance=t1)
t.save()
return HttpResponseRedirect(reverse('index'))
ついでに、save()
のたびに日付は自動更新されるようにする
todos/models.py
update_date = models.DateTimeField('date published', auto_now=True)
-
auto_now=True
をつけるだけ-
auto_now_add=True
なら登録時のみ日付が自動でささる-
insert_date
とupdate_date
で分けているなら使うべき
-
-
※ソースは一部抜粋
FormModelを(ちょっと)使ってみた
基本的にTodoForm
を使って連携するように修正 ※ただし、todo_id
だけは別途連携してる・・・
ついでに、add:登録
とupdate:更新
を共通化する。
todos/views.py
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from django.shortcuts import render
from todos.models import Todo, TodoForm
def index(request):
todo_list = Todo.objects.all()
context = {'todo_list': todo_list}
return render(request, 'todos/index.html', context)
def new(request):
context = {'form': TodoForm(), 'todo_id': ""}
return render(request, 'todos/new.html', context)
def add(request):
todo = Todo()
todo.todo_id = request.POST['todo_id']
todo_form = TodoForm(request.POST, instance=todo)
if todo_form.is_valid():
todo_form.save()
return HttpResponseRedirect(reverse('index'))
else:
return render(request, 'todos/new.html', {'form': todo_form, 'todo_id': todo_id})
def detail(request, todo_id):
todo = Todo.objects.get(todo_id=todo_id)
context = {'form': TodoForm(instance=todo), 'todo_id': todo_id}
return render(request, 'todos/new.html', context)
def delete(request, todo_id):
t = Todo.objects.get(todo_id=todo_id)
t.delete()
return HttpResponseRedirect(reverse('index'))
- パラメータ
context
をform: TodoForm()
になるように修正-
todo_id
は別で連携する
-
-
todo_form.is_valid
で登録可能かチェックを追加- ダメなら入力画面へ戻す
登録、更新をまとめたのでurl.py
からupdate
を削除する
todos/urls.py
urlpatterns = [
path('', views.index, name='index'),
path('new/', views.new, name='new'),
path('add/', views.add, name='add'),
path('<int:todo_id>/', views.detail, name='detail'),
path('delete/<int:todo_id>/', views.delete, name='delete'),
]
もちろんtemplate
も修正する
todos/templates/todos/new.html
<html>
<head></head>
<body>
<form action="/todos/add/" method="post">
{% csrf_token %}
{% for field in form.visible_fields %}
{{ field.label }}: <input type="text" name="{{ field.name }}" value="{{ field.value }}"/>
{{ field.errors }}
<br>
{% endfor %}
<input type="hidden" name="todo_id" value="{{ todo_id }}"/>
<input type="submit" value="登録"/>
</form>
</body>
</html>
-
form.visible_fields
はhidden
以外のfieldのことをさす(今回はhidden
ないけど)-
hidden
は、form.hidden_fields
を利用する -
{{ form }}
でinputタグを書かずにformを作ってくれる -
form.as_table
ならテーブルで、form.as_ul
ならリスト形式、form.as_p
なら箇条書きで出力- 個人的(最終的)には、cssとかも当てたいのでhtmlタグは自分で書きたいと思う
-
おまけ
シーケンス取得をModel
側で実施してみた
save()
を継承して、todo_id
のチェックを行い、空だったらシーケンスから採番する
todos/models.py
from django import forms
from django.db import models
from django.forms import ModelForm
from sequences import get_next_value
class Todo(models.Model):
todo_id = models.CharField(primary_key=True, max_length=5, default="")
title = models.CharField(max_length=50, default="")
main_text = models.CharField(max_length=300, default="")
update_date = models.DateTimeField('date published', auto_now=True)
def save(self, *args, **kwargs):
if self.todo_id == "":
self.todo_id = get_next_value('todo_seq')
super().save(*args, **kwargs)
class TodoForm(ModelForm):
class Meta:
model = Todo
fields = ['todo_id', 'title', 'main_text', 'update_date']
exclude = ['todo_id', 'update_date']
-
Todo
にsave()
を実装-
todo_id == ""
ならシーケンスから採番する ※やってみたけど微妙だな。って思いました。views.py
でハンドリングする方がいいと思います ※役に立つかもしれないので、残しままにします
-
おわりに
まだまだ勉強中
「自分のこうしたい!」が全く反映できずにモヤモヤ中
でも、やりたいことは別なので次に進もうと思います。