티스토리 뷰
[django 커뮤니티] 게시판 태그 추가하기 (tag, startapp tag, models.py , 게시판에 추가하기, ManyToManyField
지휘리릭 2020. 1. 21. 21:10● Tag
태그는 views.py , templates를 따로 사용하지 않는다. 왜냐면 태그는 게시물에 추가되는 것이기 때문에 따로 필요하지 않기 때문이다. 앞서 만든 Board 모델, 게시물 작성, 게시물 목록에 태그 내용을 추가해주기만 하면 된다. 추가된 태그 부분은 ### 주석처리하여 표시
● tag models.py 모델링
from django.db import models
class Tag(models.Model):
name = models.CharField(max_length=32, verbose_name="태그명")
registered_date = models.DateTimeField(auto_now_add=True, verbose_name="등록시간")
def __str__(self):
return self.name
class Meta:
db_table = "community_tag"
verbose_name = "태그"
verbose_name_plural = "태그"
태그 클래스에는 태그명과 등록시간을 필드로 추가한다. 이후에는 반드시 python manage.py makemigrations tag, python manage.py migrate tag 를 해야한다.
● tag admin.py
from django.contrib import admin
from .models import Tag
class TagAdmin(admin.ModelAdmin):
list_display = ('name', 'registered_date',)
admin.site.register(Tag, TagAdmin)
● board models.py에 tag 추가하기
from django.db import models
class Board(models.Model):
title = models.CharField(max_length=64, verbose_name="제목")
contents = models.TextField(verbose_name="내용")
registered_date = models.DateTimeField(auto_now_add=True, verbose_name = "등록 시간")
writer = models.ForeignKey('users.Users', verbose_name = "작성자", on_delete = models.CASCADE)
### 태그 추가 부분 ###
tag = models.ManyToManyField('tag.Tag', verbose_name = "태그")
def __str__(self):
return self.title
class Meta:
db_table = "community_board"
verbose_name = "게시물"
verbose_name_plural = "게시물"
- 게시물에 태그 내용을 추가한다. 태그도 작성자와 마찬가지로 다른 app의 모델을 가져오기 때문에 '(app, model이름)' 값을 준다. 하나의 태그는 여러 게시물에 사용될 수 있고, 하나의 게시물에는 여러 개의 태그를 사용할 수 있기 때문에 ManyToManyField를 사용한다.
- board 모델에 새로운 필드 값을 추가한 것이므로 board 앱에 대해서 migrations을 꼭 해야한다.
● board_detail.html, def board_write, BoardForm 에 태그 추가하기
(1) board > forms.py
- 게시물 작성폼에 태그 필드를 추가한다. 태그는 필수 항목이 아니기 때문에, required 값은 False로 설정한다.
from django import forms
class BoardForm(forms.Form):
title = forms.CharField(error_messages = {'required':"제목을 입력해주세요"}, label = "제목", max_length=128)
contents = forms.CharField(error_messages = {'required':"내용을 입력해주세요."}, label = "내용", widget = forms.Textarea)
### 태그 추가 부분 ###
tag = forms.CharField(required = False, label = "태그")
(2) board > views.py
- 태그는 게시물이 이미 완성된 상태에서 추가되야 한다. new_board 라는 객체가 생성된 후에 id가 부여되는데 태그는 그 아이디 값을 이용해서 추가되기 때문
- 리스트로 받은 태그를 콤마(,)로 구분한다.
- objects.get_or_create 메소드는 두 개의 값을 반환한다. created는 해당 태그가 기존에 있던 태그인지(True) 새로 생성된 태그인지(False) 의 Boolean 값을 반환하고. tag_는 True라면 새로 생성한 태그값이고 False라면 기존의 DB에서 가져온 태그값을 반환한다.
- 이 태그값(tag_)을 앞서 저장한 게시물(new_board)의 tag 필드에 추가한다.
- 입력된 태그가 없다면 for문을 벗어난다.
from tag.models import Tag
def board_write(request):
if not request.session.get('user'):
return redirect('/users/login')
if request.method == "GET":
form = BoardForm()
elif request.method == "POST":
form = BoardForm(request.POST)
if form.is_valid():
user_id = request.session.get('user')
user = Users.objects.get(pk = user_id)
new_board = Board(
title = form.cleaned_data['title'],
contents = form.cleaned_data['contents'],
writer = user
)
new_board.save()
### 태그 추가 부분 ###
tags = form.cleaned_data['tag'].split(',')
for tag in tags:
if not tag :
continue
else:
tag = tag.strip()
tag_, created = Tag.objects.get_or_create(name = tag)
new_board.tag.add(tag_)
return redirect('/board/list')
return render(request, 'board_write.html', {'form' :form})
- "태연" " 태연" "태연 " 세 개의 태그는 똑같은 의미인데 양쪽 공백을 제거하지 않으면 세 개의 태그로 구분되어 추가된다. 하지만 태그에 strip() 을 처리하면 하나의 문자열에 양쪽 공백을 제거한 값으로 읽힌다. 오른쪽 사진처럼 게시물을 추가했을 때 왼쪽 사진처럼 "태연" 하나의 태그만 추가된 것을 알 수 있다.
(3) templates > board_detail.html
- board_write.html 은 각 필드에 따라 출력되도록 코드를 작성하여 따로 추가되는 부분은 없고, 게시물을 보여주는 board_detail.html 에서 태그를 보여주는 부분을 추가해야한다. board 객체에서 tag 정보를 모두 가져와서 콤마로 구분해서 출력되도록 한다.
{% extends 'base.html' %}
{% block contents %}
<div class = "row mt-5">
<div class = "col-12">
<div class = "form-group">
<label for = "title">제목</label>
<input type = "text" class = "form-control" id = "title" value = "{{board.title}}" readonly>
<label for = "contents">내용</label>
<textarea class ="form-control" readonly>{{board.contents}}</textarea>
<!---태그 추가 부분-->
<labe for = "tags">태그</labe>
<span id = "tags" class = "form-control">
{{board.tag.all | join:", "}}
</span>
</div>
<button type = "button" class = "btn btn-primary" onclick = "location.href = '/board/list/'">돌아가기</button>
</div>
</div>
{% endblock %}
- 아래와 같이 board_detail.html 출력된다. 여러 개의 태그를 추가한 경우에 콤마로 구분되어 나타낸 것을 알 수 있다.
'django project > 커뮤니티' 카테고리의 다른 글
- Total
- Today
- Yesterday
- pythonanywhere배포방법
- CellForRowAt Not Called
- iOS 데이터베이스
- django 로그인접근
- Firebase 데이터베이스 추천
- 웹 배포
- 실시간 데이터베이스
- python 웹 배포
- 장고 태그달기
- 장고 게시판
- CellForRowAt 호출안됨
- Django
- django clean
- django pythoneverywhere
- 알파벳 카운팅
- django tag
- pythonanywhere배포
- 까만 화면
- cleaned_data
- Realtime Database
- iOS UITableView 출력안됨
- django 게시판
- 데이터베이스 추천
- django 태그
- 테이블출력안됨
- ModelForm Form 차이
- iOS 화면 안나옴
- UITableViewController Not Working
- iOS 검은 화면
- django 개발일지
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |