유저는 모델을 만들지 않고 장고에서 기본적으로 제공하는 모델을 사용할 예정
user-board 1:n 관계
user-reply 1:n 관계
데코레이터(자바에서는 어노테이션) @login_required()
을 추가해 login이 되어있어야만 가능하게 함
@login_required(login_url='/user/login')
로그인 안해줬을 때는 로그인 창 띄워줌, 여기서 로그인 하면 원래 가려고 했던 페이지로 가짐
urls.py
from django.contrib import admin
from django.urls import path
import board.views
import product.views
import reply.views
import user.views
urlpatterns = [
path('admin/', admin.site.urls),
path('board/create',board.views.create),
path('board/listGet',board.views.listGet),
path('board/readGet/<int:bid>',board.views.readGet),
path('board/deleteGet/<int:bid>',board.views.deleteGet),
path('board/update/<int:bid>',board.views.update),
path('reply/create',reply.views.create),
path('reply/list',reply.views.list),
path('reply/read/<int:rid>',reply.views.read),
path('reply/delete/<int:rid>',reply.views.delete),
path('reply/update/<int:rid>',reply.views.update),
path('user/signup', user.views.singup),
path('user/login', user.views.login),
path('user/logout', user.views.logout),
]
forms.py
from django import forms
from board.models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post # model은 Post 양식으로 쓰겠다.
fields = ('title', 'contents') # 어떤 필드를 입력 받을 지
exclude = ('writer', ) # 폼에서 writer 입력받지 않게 함
models.py
from django.contrib.auth.models import User
from django.db import models
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=40)
contents = models.TextField()
create_date = models.DateTimeField(auto_now_add=True)
# writer은 다른 모델을 참조하겠다.(User) 외래키 추가
writer = models.ForeignKey(User, on_delete=models.CASCADE) # on_delete : User가 delete 될 때 게시글을 어떻게 설정한 것인지에 대해 설정 1. 게시글 같이 지우기(CASCADE) 2. 없는 값으로 해서 게시글은 남겨두기
def __str__(self):
return 'id : {}, title : {}'.format(self.id, self.title, self.contents)
views.py
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.shortcuts import render, redirect
# Create your views here.
from board.forms import PostForm
from board.models import Post
@login_required(login_url='/user/login')
def create(request):
if request.method == "GET": # 작성하거나 수정할 페이지 띄워줌
# postForm을 이용해 정보를 받아옴
postForm = PostForm()
context = {'postForm' : postForm}
return render(request, 'board/create.html',context)
elif request.method == "POST": # 실제 그 내용이 DB에 저장되도록
# postForm을 받아와 유효성 확인이 되면, save 해줌
postForm = PostForm(request.POST)
if postForm.is_valid():
post = postForm.save(commit=False)
post.writer = request.user # 현재 로그인한 사용자를 writer로 고정시켜줘야함
post.save()
return redirect('/board/readGet/'+str(post.id)) # 자기가 쓴 게시물 조회로 가도록 함
def listGet(request):
posts = Post.objects.all().order_by('-id') # id 순으로 정렬하는데 - 니까 오름차순으로 정렬
context = {'posts' : posts}
return render(request, 'board/list.html',context)
def readGet(request, bid):
# post = Post.objects.filter(id=bid)
post = Post.objects.get(Q(id=bid)) # Q (장고에 있는 모델) 이용해서 하나만 조회 가능 (filter은 for문 해야하는데 이 경우 하나만 가능)
context = {
'post' : post
}
return render(request, 'board/read.html',context)
@login_required(login_url='/user/login')
def deleteGet(request,bid):
post = Post.objects.get(id=bid) # Q 안쓰고도 가능, Q는 쿼리 들어갈 때 여러 기능
# writer와 현재 user가 같을 때만 삭제 시켜줘야 함
if request.user != post.writer:
return redirect('/board/listGet')
post.delete()
return redirect('/board/listGet') # board의 list url로 redirect 되게 함
@login_required(login_url='/user/login')
def update(request,bid):
# 해당 게시글이 한번 조회가 되어야 함
post = Post.objects.get(id=bid)
if request.method == "GET" : # 작성하거나 수정할 페이지 띄워줌
postForm = PostForm(instance=post) # 조회 된 postForm을 유지해서 가져와야 함
context = {'postForm' : postForm}
return render(request,'board/create.html',context) # 수정할 페이지를 띄워줌
elif request.method == "POST" : # 실제 그 내용이 DB에 저장되도록
postForm = PostForm(request.POST, instance=post) # 위에서 받아온 게시물의 내용을 Form으로 받아옴
if postForm.is_valid():
post = postForm.save(commit=False)
post.save()
return redirect('/board/readGet/'+str(post.id))# 수정 후 조회하는 곳으로 이동
create.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
{% csrf_token %}
{{ postForm }}
<button>작성</button>
</form>
</body>
</html>
list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- authenticated가 되어있으면(True) 글씨를 뜨게 함-->
{% if request.user.is_authenticated%}
로그인 한 사용자 : {{ request.user }} <br/>
{% endif %}
{% for post in posts %}
{{ post.id }}
<!-- postid에 해당하는 contents를 클릭하면 해당 id의 readGet으로 이동 -->
<a href="readGet/{{ post.id }}"> {{ post.contents }} </a>
{{ post.writer }}
<br/>
{% endfor %}
<a href="../board/create">게시글 작성</a>
</body>
</html>
read.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if post %}
{{ post.id }}
{{ post.title }} <br/>
<a href="/board/listGet">목록</a>
<!--작성자와 로그인 한 유저가 일치해야만 수정, 삭제 버튼이 보이도록 함 -->
{% if post.writer == request.user %}
<a href="/board/update/{{post.id}}">수정</a>
<a href="/board/deleteGet/{{post.id}}">삭제</a>
{% endif %}
{% endif %}
</body>
</html>
views.py
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.shortcuts import render, redirect
from django.contrib.auth import login as auth_login, logout as auth_logout # login함수이름과 겹쳐서 auth_login으로 해줌
# 회원가입
def singup(request):
if request.method == "GET":
signupForm = UserCreationForm() # 장고에서 제공하는 유저 Form
return render(request,'user/signup.html', {'signupForm':signupForm})
elif request.method == "POST":
signupForm = UserCreationForm(request.POST)
if signupForm.is_valid():
user = signupForm.save(commit=False)
user.save()
return redirect('/board/listGet') # 회원가입 하면 게시글 목록으로 가도록 이동시켜줌
# 로그인 입력 양식이 주어져야함
def login(request):
if request.method == "GET":
loginForm = AuthenticationForm() # 로그인 시 사용하는 Form
return render(request,'user/login.html', {'loginForm' : loginForm})
elif request.method == "POST":
loginForm = AuthenticationForm(request, request.POST) # request와 request.POST를 둘 다 넣어주어야 함
if loginForm.is_valid():
auth_login(request, loginForm.get_user()) # request, 유저정보를 뽑아 넣어줌 id, pw를 직접 뽑아내서 아이디 비번 맞는지 할 필요 없이 이렇게 하면됨
return redirect('/board/listGet')
def logout(request):
# 세션 정보를 지우는 것
auth_logout(request)
return redirect('/board/listGet')
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
{% csrf_token %}
{{ loginForm }}
<button>로그인</button>
</form>
</body>
</html>
signup.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
{% csrf_token %}
{{ signupForm }}
<button>회원가입</button>
</form>
</body>
</html>
forms.py
from django import forms
from reply.models import Reply
class ReplyForm(forms.ModelForm):
class Meta:
model = Reply # model은 Post 양식으로 쓰겠다.
fields = ('contents',) # 어떤 필드를 입력 받을 지
exclude = ('writer',)
models.py
from django.contrib.auth.models import User
from django.db import models
# Create your models here.
class Reply(models.Model):
contents = models.TextField()
create_date = models.DateTimeField(auto_now_add=True)
writer = models.ForeignKey(User, on_delete=models.CASCADE)
views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
# Create your views here.
from reply.forms import ReplyForm
from reply.models import Reply
@login_required(login_url='/user/login')
def create(request):
if request.method == "GET":
replyForm = ReplyForm()
context = {'replyForm':replyForm}
return render(request, 'reply/create.html', context)
elif request.method == "POST":
replyForm = ReplyForm(request.POST)
if replyForm.is_valid():
reply = replyForm.save(commit=False) # 저장 전 확인
reply.writer = request.user
reply.save()
return redirect('/reply/read/'+str(reply.id)) # 자신이 쓴 댓글로 가도록함
def read(request,rid):
reply = Reply.objects.get(id=rid)
context = {
'reply' : reply
}
return render(request,'reply/read.html',context)
def list(request):
replys = Reply.objects.all().order_by('-id')
context = {
'replys' : replys
}
return render(request, 'reply/list.html',context)
def delete(request,rid):
reply = Reply.objects.get(id=rid)
reply.delete()
return redirect('/reply/list')
def update(request,rid):
reply = Reply.objects.get(id=rid)
if request.method == "GET":
replyForm = ReplyForm(instance=reply)
context = {'replyForm':replyForm}
return render(request, 'reply/create.html', context)
elif request.method == "POST":
replyForm = ReplyForm(request.POST, instance=reply)
if replyForm.is_valid():
reply = replyForm.save(commit=False) # 저장 전 확인
reply.save()
return redirect('/reply/read/'+str(reply.id)) # 자신이 쓴 댓글로 가도록함
return render()
create.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
{% csrf_token %}
{{ replyForm }}
<button>전송</button>
</form>
</body>
</html>
list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for reply in replys %}
{{ reply.id }}
{{ reply.writer }}
<!-- postid에 해당하는 contents를 클릭하면 해당 id의 readGet으로 이동 -->
<a href="read/{{ reply.id }}"> {{ reply.contents }} </a>
{{post.create_date}} <br/>
{% endfor %}
</body>
</html>
read.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if reply %}
{{ reply.id }}
{{ reply.contents }} <br/>
<a href="/reply/update/{{reply.id}}">수정</a>
<a href="/reply/delete/{{reply.id}}">삭제</a>
{% endif %}
</body>
</html>