10/5 오늘의 시간표
09:00 ~ 10:00 [프로젝트] 장고 클론코딩 프로젝트1
10:00 ~ 11:00 [프로젝트] 장고 클론코딩 프로젝트1
11:00 ~ 12:00 [프로젝트] 장고 클론코딩 프로젝트1
12:00 ~ 13:00 [프로젝트] 장고 클론코딩 프로젝트1
13:00 ~ 14:00 점심식사
14:00 ~ 15:00 [프로젝트] 장고 클론코딩 프로젝트1
15:00 ~ 16:00 [프로젝트] 장고 클론코딩 프로젝트1
16:00 ~ 17:00 [프로젝트] 장고 클론코딩 프로젝트1
17:00 ~ 18:00 [프로젝트] 장고 클론코딩 프로젝트1
18:00 ~ 19:00 저녁식사
19:00 ~ 20:00 [프로젝트] 장고 클론코딩 프로젝트1
20:00 ~ 21:00 [프로젝트] 장고 클론코딩 프로젝트1
오늘까지가 장고 인스타그램 클론코딩 프로젝트날이다. 남은 기능들이 많아서 아침부터 쉬지않고 계속 달려야했다.
장고 인스타그램 클론코딩 프로젝트
어제까지 user앱의 대부분의 기능은 끝냈고 오늘은 post의 기능들을 만들어야 했다.
post앱의 가장 핵심이자 기초가되는 기능이다. 해당 기능이 작동해야 따라오는 나머지 기능들을 만들 수 있으므로 시간과 노력을 투자해 최대한 빠르게 만들려고 노력했다.
@login_required
def make_post(request):
return render(request, 'make_post.html')
@login_required
def create_post(request):
user = request.user
post = Post()
post.title = request.POST.get('title')
post.body = request.POST.get('body')
post.pub_date = timezone.datetime.now()
post.nickname = user
post.save()
return redirect('/detailed_post/' + str(post.id))
make_post라는 함수는 메인페이지에서 게시글 작성버튼을 누르게되면 작성페이지로 이동하기 위해 만든 함수이고 create_post가 DB에 값을 저장하는 함수이다. 게시글의 제목과 본문, 닉네임을 저장하였으며 post.pub_date에 글이 작성된 시간을 저장하도록 했는데 이것은 나중에 메인 페이지에서 작성된 게시글들을 시간순으로 정렬하기 위해 추가한 값이다. 게시글이 작성되면 상세 페이지에서 작성된 글을 볼 수 있는데 게시글마다 고유의 id값을 저장하여 그 값을 통해 해당 게시물로 접근할 수 있도록 설정해두었다.
@login_required
def detailed_post(request, post_id):
post_detail = get_object_or_404(Post, pk=post_id)
write_comment = Comment.objects.filter(post_id=post_id).order_by('-created_at')
return render(request, 'detailed_post.html', {'post': post_detail, 'comment': write_comment})
그 상세페이지를 띄우는 함수가 이것인데 각 게시물의 pk값을 가져와 post_id로 저장해두고 여러곳에서 유용하게 쓸 수 있었다. write_comment는 게시글에 댓글을 달 수 있는 기능을 하도록 설정한 함수이다. 차후에 댓글기능을 설명할때 추가로 설명하도록 하겠다.
from django.urls import path
from post import views
app_name = 'post'
urlpatterns = [
path('detailed_post/<int:post_id>', views.detailed_post, name='detailed_post'),
path('make_post/', views.make_post, name='make_post'),
path('create_post', views.create_post, name='create_post'),
]
지금까지 만든 함수들이 각각의 페이지에서 기능하도록 urls.py에 넣어두었다.
이제 게시글 작성기능을 완성했으니 다음은 게시글 수정과 삭제기능을 만들어야 했다.
게시글 삭제 기능은 만들기가 매우 쉬웠다.
@login_required
def delete_post(request, post_id):
post = Post.objects.get(id=post_id)
post.delete()
return redirect('/')
삭제하려는 게시글의 id값만 가져와 해당 게시글을 delete하기만 하면되는 쉬운 함수이다. 삭제가 완료되면 메인페이지로 이동하도록 설정해 두었다.
다음은 게시글 수정기능인데 여기서 애를 좀 많이 먹었었다.
@login_required
def edit_post(request, post_id):
post = Post.objects.get(id=post_id)
if request.method =='POST':
form = Postedit(request.POST)
if form.is_valid():
user = request.user
post.title = form.cleaned_data['title']
post.body = form.cleaned_data['body']
post.pub_date=timezone.now()
post.nickname = user
post.save()
return redirect('/detailed_post/' + str(post.id))
else:
form = Postedit(instance = post)
return render(request,'edit_post.html', {'form':form})
DB에 저장된 값을 불러와서 해당 값을 수정하고 다시 DB로 보내는 것인데, 사실 여기서 views.py에 함수를 만드는 것보다 문제였던 것이 html상에서 DB에있는 값을 가져오는 것이 더 큰 문제였다.
<form action="" method="post">
{% csrf_token %}
<div class="make_title">
<label for="make_title" class="post">글 제목</label>
<input id="title" class="form-control" placeholder={{ form.title }}</input>
<label for="write_post" class="post">게시글 작성</label>
<textarea class="form-control" id='write_post' style="resize: none" name='body' id="write_post" {{ form.body }}</textarea>
</div>
<button type="submit" class="btn-hover color-2" style="float:right;">Save</button>
</form>
</div>
make_post.html을 그대로 가져와 본문내용만 수정하도록 하였는데 DB의 데이터값을 가져오려고 하면 포스트박스에 우리팀이 만든 CSS양식이 적용이 안되고 CSS를 포기하자니 홈페이지의 구성자체가 무너질 것 같아서 별로였다. 이를 해결하기 위해 구글링을 통해 여러가지 방법들을 모색해봤지만 결국 답은 form기능을 사용하는 것이었는데 한번도 제대로 사용해본적이 없어서 시간을 많이 사용했던 것 같다.
from django import forms
from .models import Post, Comment
class Postedit(forms.ModelForm):
class Meta:
model = Post
fields = ['title','body']
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['post','nickname','comment']
결국 forms.py를 새로 만들어 class를 추가해서 이를 관리하게했고 CSS를 적용하는 방법은 따로 클래스를 만들어서 부트스트랩처럼 그 값 자체를 앱 전체에 적용되도록 하는 방법이 있긴 했지만 너무 시간이 오래걸리고 설명을 들어도 따라가기 힘들어 따로 튜터님이 구글링을 통해 찾아주신 방법을 이용해 각각의 textarea안에 직접적으로 해당 값을 집어넣어서 어거지로 양식이 유지되도록 만들기는 했다. 이 부분은 다음에 기회가 된다면 다시 한번 방법을 탐구해보도록 해야겠다.
게시글 작성이 완료되었으니 이제는 댓글 작성 기능이었다. 사실 댓글 작성기능을 먼저 하고계시는 분이 있었지만 DB에 값이 올라가지 않아 결국 그 원인을 찾기위해 다같이 머리를 싸매고 고민했다. 하지만 원인을 찾지 못하고 튜터님을 찾아가기에는 너무 늦은 새벽시간이라 찾아갈 수 없어 결국 장고 원격강의 자료의 코드를 그대로 가져와 DB에 올릴 값들만 수정하고 댓글 html양식을 여기에 맞게 수정하였다.
def write_comment(request, post_id):
if request.method == 'POST':
comment = request.POST.get('comment','')
current_post = Post.objects.get(id=post_id)
C = Comment()
C.comment = comment
C.nickname = request.user
C.post = current_post
C.save()
return redirect('/detailed_post/'+str(post_id))
<form action="{% url 'post:write_comment' post.id %}" method="post">
{% csrf_token %}
{% if error %}
<div class="alert alert-danger" role="alert">
{{ error }}
</div>
{% endif %}
<div class="comment_box_2">
<div class="now_user_name">
<h5>{{ user.nickname }}</h5>
</div>
<div class="comment_write">
<input type="text" class="form-control" id="comment_write" placeholder="댓글을 남겨주세요" name='comment'>
<button class="comment_save_btn" type="submit"> 게시 </button>
</div>
</div>
</form>
<form action="{% url 'post:delete_comment' %}" method="post">
{% csrf_token %}
{% for cm in comment %}
<div class="comment_box_1">
<div class="comment_writer_list">
<h4> Name | {{ cm.nickname }}</h4>
</div>
<div class="comment_list">
<h4> 댓글 | {{ cm.comment }}</h4>
<button class="comment_delete_btn" onclick="location.href='/delete_comment'" > 삭제 </button>
</div>
</div>
{% endfor %}
<form action="{% url 'post:write_comment' post.id %}" method="post">
여기서는 action으로 "/write_comment/post_id"로 리다이렉트 했는데 튜터님이 이렇게 하면 오류가 발생할 확률이 높기 때문에 {% url %}을 사용하는 것이 안정성 측면에서 훨씬 좋고 실무에서도 이 방식이 거의 정석에 가깝다고 하셔서 해당 방식으로 바꿨고 {% csrf_token %}의 경우 form 박스가 생성되면 그때마다 추가해줘야하는데 한번만들어두면 그 아래로 쭉 적용되는줄 알고 아래 form박스에는 추가를 안했더니 오류가 발생해 이 또한 튜터님이 알려주셔서 수정할 수 있었다.
메인페이지에는 가장 최근에 작성된 게시글이 맨 위로오도록 해두었다. 여기서 우측상단의 버튼중 +Post라는 버튼을 누르면
이렇게 게시글 작성 페이지로 이동된다. 게시글의 제목과 본문을 입력후 Save를 누르면
이렇게 상세페이지로 이동된다. 여기서 Edit버튼을 누르면
게시글 수정페이지로 이동되고
게시글을 수정할 수 있다.
아래로 내려보면 댓글창이 있는데 댓글을 작성하고 게시버튼을 누르면
댓글이 작성된다. 이제 여기서 Delete버튼을 누르면
게시글을 삭제할 수 있다. 여기까지가 오늘 구현한 post앱의 기능들이다.
오늘 하루를 마치며
오늘은 post앱 내의 기능들을 거의 다 만들었는데 새벽 4시까지 작업을 했음에도 불구하고 아직 완성못한기능이 남았었다. 마지막에 댓글기능에서 나온 오류들은 사실 자고 일어나서 아침에 튜터님께 질문을 하고 답변을 받는 내용이고 댓글 삭제기능도 구현을 못한 상태이다. 이렇게 늦은 시간까지 작업을 했는데도 끝이 보이지가 않는것을 보니 시간 배분을 너무 안일하게 생각하고 여유를 많이 둔 것이 문제였던 것 같다. 앞으로는 초반에 조금 힘이 들더라도 열심히해서 미리 끝내고 여유롭게 시간을 보내는 식으로 시간배분을 하는 것이 좋을 것 같다.