🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

2358閲覧

Todoアプリで完了ボタンを押すと完了したタスクが下に移動するようにしたい

reol-777

総合スコア14

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2020/12/31 07:52

編集2021/01/03 06:56

Todoアプリで完了ボタン(✔ボタン)を押すと完了したタスクが下に(ページネーションの下)移動するようにしたいです

イメージ説明
イメージ説明

・コード(完了ボタンの処理はなし)

model

1from django.db import models 2from django.utils import timezone 3# Create your models here. 4class Category(models.Model): 5 class Meta: 6 db_table = "category" 7 verbose_name = "カテゴリ" 8 verbose_name_plural = "カテゴリ" 9 10 category_name = models.CharField(max_length=255,unique=True,verbose_name="カテゴリの名前",null=True) 11 12 def __str__(self): 13 return self.category_name 14 15PRIORITY = (('danger','high'),('info','normal'),('success','low')) 16class TodoModel(models.Model): 17 class Meta: 18 db_table = "todomodel" 19 verbose_name = "todoモデル" 20 verbose_name_plural = "todoモデル" 21 22 title = models.CharField(max_length=100,verbose_name="タイトル") 23 memo = models.TextField(verbose_name="メモ") 24 priority = models.CharField( 25 max_length = 50, 26 choices = PRIORITY, 27 verbose_name="優先度" 28 ) 29 duedate = models.DateTimeField(verbose_name="期日",default=timezone.now) 30 category = models.ForeignKey(Category,on_delete = models.PROTECT,verbose_name="カテゴリ",null=True) 31 def __str__(self): 32 return self.title 33

view

1from django.shortcuts import render 2from django.views.generic import ListView,CreateView,UpdateView 3from .models import TodoModel 4from django.urls import reverse_lazy 5from django_filters.views import FilterView 6from .filters import TodoFilter 7from django.shortcuts import redirect 8from .form import TodoForm 9from django.conf import settings 10import datetime 11from django.core.mail import send_mail 12# Create your views here. 13 14class TodoList(FilterView): 15 template_name = 'list.html' 16 model = TodoModel 17 paginate_by = 10 18 19 filterset_class = TodoFilter 20 strict = False 21 22 def get(self, request, **kwargs): 23 if request.GET: 24 request.session['query'] = request.GET 25 else: 26 request.GET = request.GET.copy() 27 if 'query' in request.session.keys(): 28 for key in request.session['query'].keys(): 29 request.GET[key] = request.session['query'][key] 30 31 return super().get(request, **kwargs) 32 33# 削除ボタンの処理 34 def post(self,request): 35 delete_pk = request.POST['delete'] 36 TodoModel.objects.filter(pk=delete_pk).delete() 37 return redirect('list') 38 39# 通知処理 40 nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M') 41 time = datetime.datetime.strptime(nowtime,'%Y-%m-%d %H:%M') 42 todo_obj = TodoModel.objects.all() 43 for obj in todo_obj: 44 if time == (obj.duedate - datetime.timedelta(minutes=1)): 45 subject = 'タイトル:{}'.format(obj.title) 46 massege = 'メモ:{}\n期日:{}\nカテゴリ:{}\n'.format(obj.memo,obj.duedate,obj.category) 47 from_mail = [] 48 recipient = [settings.EMAIL_HOST_USER] 49 send_mail(subject, massege, from_mail, recipient) 50 51class TodoCreate(CreateView): 52 template_name = 'create.html' 53 model = TodoModel 54 form_class = TodoForm 55 success_url = reverse_lazy('list') 56 57 58class TodoUpdate(UpdateView): 59 template_name = 'update.html' 60 model = TodoModel 61 fields = ('title','memo','priority','duedate','category') 62 success_url = reverse_lazy('list') 63

listhtml

1{% extends 'base.html' %} 2{% load crispy_forms_tags %} 3 4{% block customcss %} 5 <link href="https://use.fontawesome.com/releases/v5.15.1/css/all.css" rel="stylesheet"> 6 <script src="https://kit.fontawesome.com/5b1578e2a2.js" crossorigin="anonymous"></script> 7{% endblock customcss %} 8 9{% block content %} 10<!-- ヘッダー --> 11<div class="jumbotron jumbotron-fluid"> 12 <div class="container"> 13 <h1 class="display-4"><a class="title" href="#">Todo List</a></h1> 14 <p class="lead">TodoListを使って毎日を効率的に過ごしましょう。</p> 15 </div> 16</div> 17 18<!-- モーダル 絞り込み検索--> 19<div class='container'> 20 <div id="myModal" class="modal fade" tabindex="-1" role="dialog"> 21 <div class="modal-dialog" role="document"> 22 <div class="modal-content"> 23 <div class="modal-header"> 24 <h5 class="modal-title">絞り込み検索</h5> 25 <button type="button" class="close" data-dismiss="modal" aria-label="閉じる"> 26 <span aria-hidden="true">&times;</span> 27 </button> 28 </div> 29 <form id="filter" method="get"> 30 <div class="modal-body"> 31 {{filter.form|crispy}} 32 </div> 33 </form> 34 <div class="modal-footer"> 35 <a class="btn btn-outline-secondary" data-dismiss="modal">戻る</a> 36 <button type="submit" class="btn btn-outline-secondary" form="filter">検索</button> 37 </div> 38 </div> 39 </div> 40 </div> 41 42 43 <div class="create"><a href="{% url 'create' %}" class="btn btn--orange btn--cubic btn--shadow" tabindex="-1" role="button" aria-disabled="true">NEW LIST</a></div> 44 <div class="search"><a class="btn btn-outline-secondary" data-toggle="modal" data-target="#myModal" href="#">SEARCH</a></div> 45 46<!-- タスク --> 47 {% for item in object_list %} 48 <div class="alert alert-{{ item.priority }}" role="alert"> 49 <!-- 完了ボタン --> 50 <form action="" method="POST" style="display:inline;">{% csrf_token %} 51 <button class="Button-style" type="submit" name="done" value="{{item.pk}}">✔</button> 52 </form> 53 <p class="item_object">TITLE:{{ item.title}} LIMIT:{{ item.duedate|date:"Y-m-d H:i" }} CATEGORY:{{ item.category }}</p> 54 <a data-toggle="modal" data-target="#DetailModal{{ item.pk }}" class="btn2 btn--detail btn--circle btn--shadow--a" tabindex="-1" role="button" aria-disabled="true"><i class="fas fa-eye fa-3x" data-fa-transform="shrink-8 up-5 left-1.05"></i></a> 55 <a data-toggle="modal" data-target="#DeleteModal{{ item.pk }}" class="btn2 btn--delete btn--circle btn--shadow--a" tabindex="-1" role="button" aria-disabled="true"><i class="fas fa-trash-alt fa-3x" data-fa-transform="shrink-8 up-5 right-1.1"></i></a> 56 <a href="{% url 'update' item.pk %}" class="btn2 btn--update btn--circle btn--shadow--a" tabindex="-1" role="button" aria-disabled="true"><i class="fas fa-pen-fancy fa-3x" data-fa-transform="shrink-8 up-5"></i></a> 57 </div> 58 59 <!-- モーダル 削除画面 --> 60 <div class="modal fade" id="DeleteModal{{ item.pk }}" tabindex="-1" role="dialog" aria-labelledby="basicModal" aria-hidden="true"> 61 <div class="modal-dialog"> 62 <div class="modal-content"> 63 <div class="modal-header"> 64 <h4 class="modal-title" id="myModalLabel">削除確認画面</h4> 65 </div> 66 <div class="modal-body"> 67 <label>データを削除しますか?</label> 68 <p>TITLE:{{ item.title}} LIMIT:{{ item.duedate|date:"Y-m-d H:i" }} CATEGORY:{{ item.category }}</p> 69 </div> 70 <div class="modal-footer"> 71 <form action="" method="POST">{% csrf_token %} 72 <button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button> 73 <button type="submit" class="delete-button" name="delete" value="{{item.pk}}">削除</button> 74 </form> 75 </div> 76 </div> 77 </div> 78 </div> 79 <!-- モーダル 詳細画面 --> 80 <div class="modal fade" id="DetailModal{{ item.pk }}" tabindex="-1" role="dialog" aria-labelledby="basicModal" aria-hidden="true"> 81 <div class="modal-dialog"> 82 <div class="modal-content"> 83 <div class="modal-header"> 84 <h4 class="modal-title" id="myModalLabel">詳細画面</h4> 85 </div> 86 <div class="modal-body"> 87 <p>タイトル:{{ item.title }}</p> 88 <p>メモ:{{ item.memo|linebreaksbr }}</p> 89 <p>期日:{{ item.duedate|date:"Y-m-d H:i" }}</p> 90 <p>カテゴリ:{{ item.category }}</p> 91 </div> 92 <div class="modal-footer"> 93 <button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button> 94 </div> 95 </div> 96 </div> 97 </div> 98 99 {% empty %} 100 <li class="list-group-item"> 101 対象のデータがありません 102 </li> 103 {% endfor %} 104</div> 105<!-- ページネーション読み込み --> 106 {% include "./pagination.html" %} 107{% endblock content %} 108

とりあえず、完了ボタンはつけたのですが、viewやhtmlにどのような処理を書けばよいかわかりません。viewに、

def done(self,request): done_pk = request.POST('done') context = {'done':TodoModel.objects.filter(pk=done_pk)} return render(request,'list.html',context)

このように書いてみましたが、うまくいきませんでした。
一例としてどのような書き方がありますか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ryo2003

2021/01/09 23:13

私自身まだ初学者なので間違っていたら申し訳ないんですが、 最後のviewに書いてる request.POST('done')で欲しいpk受け取れてますか?
guest

回答1

0

models.py のtodoモデルに、完了フラグ(変数名は done でも良いです)を持たせましょう。
その上で、完了フラグの値によって、ページネーションの上に表示するか、下に表示するかを、queryも場合分けして記述すれば良いはずです。

もし、完了フラグ という名前とするならば、デフォルト(ToDoの新規登録時)は false、完了時に True とするのが分かり易いかと思います。

request.POST('done')で欲しいpk受け取れてますか?

request.POST['done'] でしょうかね。

 

加えて、(レコードを論理削除するならば)削除フラグも必要ですね。
(レコードを物理抹消するならば不要です。)

投稿2021/01/16 07:23

_whitecat_22

総合スコア1305

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問