당신은 멋쟁이, 우리는 장고쟁이~

0%

TodoList 14편 - 투두리스트 생성 구현

TodoList Create 페이지 구현


투두리스트를 생성하는것을 구현해 보려 합니다.


클래스 기반 뷰인 CreateView 를 사용해 보려 했었는데. 잘 모르겠어서. 함수형 으로 진행 했습니다.


forms 적용 하는것에서 꼬이고, 함수기반 뷰 작성할때 꼬이고, 클래스 기반 뷰에서도 꼬이고,


Bulma CSS 적용할때 꼬이고, URL 설정할때 꼬여서. 매우 힘들게 구현한것 같습니다;;;


아래와 같이 진행 해봅니다.



todo_list.html 파일 수정


templates/todo/todo_list.html 파일을 수정해줍니다.


생성하기 버튼을 추가 하고, 링크를 연결해줍니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
{% extends 'base.html' %}

{% block title %}할일 목록{% endblock %}

{% block content %}
<div class="box has-text-centered">
<a href="{% url 'todo:todolist_create' %}">
<button class="button is-info is-rounded is-fullwidth">할일 추가하기</button>
</a>
</div>

<div class="columns">
{% for todo in to_do_list %}
....

todo/forms.py 파일 생성 후 작성



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from django import forms 

class TodoCreateForm(forms.Form):
name = forms.CharField(
max_length=20,
widget=forms.TextInput(
attrs={
'class': 'input',
'placeholder': '해야할일',
}
)
)

description = forms.CharField(
max_length=200,
widget=forms.Textarea(
attrs={
'class': 'textarea',
'placeholder': '할일에 대한 디테일',
}
)
)

date_deadline = forms.DateField(
widget=forms.DateInput(
attrs={
'id': 'datepicker',
'placeholder': 'YYYY-MM-DD',
}
)
)

images = forms.ImageField(
widget=forms.ClearableFileInput(
attrs={
'multiple': True,
'class': 'file-input',
}
), required=False,
)

files = forms.FileField(
widget=forms.ClearableFileInput(
attrs={
'multiple': True,
'class': 'file-input',
}
), required=False,
)


todo/views.py 파일 수정


함수기반 뷰인 TodoCreate 를 추가해줌


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from .forms import TodoCreateForm

def TodoCreate(request):
if request.method == "POST":
form = TodoCreateForm(request.POST)

name = request.POST['name']
description = request.POST['description']
date_deadline = request.POST['date_deadline']
images = request.FILES.getlist('images')
files = request.FILES.getlist('files')
date_created = date.today()

# valid 한 date_deadline value 를 넣지 않았을때 막을 방법이 없음.
# date_created 가 date_deadline 보다 지난 날짜라도, Todo는 생성되는 문제점도 있음

t = TodoList.objects.create(
name=name,
description=description,
date_created=date_created,
date_deadline=date_deadline,
)

t.save()

for image in images:
TodoList_images.objects.create(todo=t, image=image)

for file_in_list in files:
TodoList_files.objects.create(todo=t, files=file_in_list)

return redirect('/')

else:
form = TodoCreateForm()
return render(request, 'todo/create.html', {'form': form})

create.html 파일 생성후 작성 (폼 작성)


templates/todo/create.html 파일을 생성하고, 작성해 줍니다.


BULMA 공식 페이지에서, components 에 대한 섹션을 참고해 가면서. 하나하나 구현 해 봅니다.


포인트는, forms.py 에 작성된 필드들의 클래스가 Bulma css 에 존재하는 클래스명으로 나와야 합니다.


  • 그리고, image 인풋과 file 인풋은, 다른 클래스를 가지고 있기 때문에,

    field.name 이 image 혹은 file 이라면, 일반 form div 가 아닌, 클래스명을 가진 div 로 표시되게 만들었습니다. (이게 if field.name == ‘image’ or filed.name == ‘file’ 이 하는 일입니다.)

  • script태그 안에, datepicker() 함수를 넣어서, deadline_date 을 선택할때, 날짜를 선택하는 위젯을 구현해 주었습니다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
{% extends 'base.html' %}
{% block head %}



<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$( function() {
$( "#datepicker" ).datepicker();
} );
</script>

{% endblock %}

{% block content %}


<article class="message is-info">

<div class="message-header">
<p>Todo List 추가</p>
<button class="delete" aria-label="delete"></button>
</div>
<div class="message-body">
새로운 투두 리스트를 추가해 보세요!
</div>

</article>


<div class="columns is-centered">

<form action="" method="POST" enctype="multiplart/form-data" style="margin-top: 50px;">
{% csrf_token %}
{% for field in form %}

{% if field.name == 'images' or field.name == 'files' %}

{{ field.name }}
<div class="file has-name" style="margin-top: 10px;">
<label class="file-label">
{{ field }}
<span class="file-cta">
<span class="file-icon">
<i class="fas fa-upload"></i>
</span>
<span class="file-label">
Choose {{ field.name }} to upload
</span>
</span>
<span class="file-name">
Upload your {{ field.name }} here
</span>
</label>


</div>

{% else %}

<div class="field" style="margin-top: 10px;">
{{ field.name }}
<div class="control">
{{ field }}
</div>
</div>
{% endif %}
{% endfor %}

<div class="field is-grouped is-grouped-centered" style="margin-top: 30px;">
<div class="control">
<button class="button is-link">Submit</button>
</div>
<div class="control">
<button class="button is-danger is-light">Cancel</button>
</div>
</div>
</form>
</div>
{% endblock %}

여기서 한가지 정말 아쉬운것 하나는, 날짜를 입력해야하는 필드에 date picker 를
자바스크립트를 사용하여 구현하고 싶었지만, 짧은 지식으로 인하여,


아직까지 제대로 구현하지 못했다는 점입니다.



URL 설정


todo/urls.py 파일에서, url 을 설정해주어야 합니다.


create/ 로 접속하면, TodoCreate 함수가 호출되게 URL 설정을 해줍니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
from django.contrib import admin
from django.urls import path
from .views import IndexView, DetailView, DeleteView, UpdateView, TodoCreate

app_name = 'todo'

urlpatterns = [
path('', IndexView.as_view(), name='todolist'),
path('detail/<int:pk>/', DetailView.as_view(), name="todolist_detail"),
path('delete/<int:pk>/', DeleteView.as_view(), name="todolist_delete"),
path('update/<int:pk>/', UpdateView.as_view(), name='todolist_update'),

path('create/', TodoCreate, name='todolist_create'),
]


마치며..


많은것이 찝찝한,,, 그리고 많이 아쉬운 부분이 많습니다;;


일단, 아래 같이 추가가 제대로 동작하긴 하지만, 개선점이 많아 보입니다.






submit 버튼을 누르면, 메인페이지 이동후, 방금 생성한 투두리스트가 나타나는것을 볼수 있습니다.