hyeonga_code
파이선 웹구축_장고_26_페이징 기능까지 구현 본문
- 페이징 기법까지 적용한 전체 코드
1. <config> > 'settings.py'
'settings.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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = 'django-insecure-a)ms^w63$yve_^r#lob$#)ut6#q#@gqz%-cwljv&c9i_$p$h)o'
DEBUG = True
ALLOWED_HOSTS = []
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'acc.apps.AccConfig',
'board.apps.BoardConfig',
'mathfilters'
]
AUTH_USER_MODEL = "acc.User"
MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR/'media'
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'config.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR/'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'config.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
AUTH_PASSWORD_VALIDATORS = [
{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',},
{'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', },
{'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', },
{'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',},
]
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Asia/Seoul'
USE_I18N = True
USE_TZ = False
STATIC_URL = 'static/'
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
cs |
2. <config> > 'urls.py'
=====
1
2
3
4
5
6
7
8
9
10
11
|
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from . import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('acc/', include('acc.urls')),
path('board/', include('board.urls')),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
cs |
3. <acc> 앱 생성 > 'models.py'
'models.py'
=====
1
2
3
4
5
6
7
8
9
10
11
12
|
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pic = models.ImageField(upload_to="usr/%y/%m")
comment = models.TextField()
age = models.IntegerField(default=0)
def getpic(self):
if self.pic:
return self.pic.url
return "/media/noimage.png"
|
cs |
4. <acc> > 'admin.py'
'admin.py'
=====
1
2
3
|
from django.contrib import admin
from .models import User
admin.site.register(User)
|
cs |
5. <acc> > 'urls.py'
'urls.py'
=====
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
from django.urls import path
from . import views
app_name = "acc"
urlpatterns = [
path('index/', views.index, name="index"),
path('login/', views.ulogin, name="login"),
path('logout/', views.ulogout, name="logout"),
path('profile/', views.profile, name="profile"),
path('delete/', views.delete, name="delete"),
path('signup/', views.signup, name="signup"),
path('update/', views.update, name="update"),
path('chpass/', views.chpass, name="chpass")
]
|
cs |
6. <acc> > 'views.py'
'views.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
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
|
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.hashers import check_password
from .models import User
def update(request):
if request.method == "POST":
u = request.user
uc = request.POST.get("ucomm")
um = request.POST.get("umail")
pi = request.FILES.get("upic")
u.email , u.comment = um, uc
if pi:
u.pic.delete()
u.pic = pi
u.save()
return redirect("acc:profile")
return render(request, "acc/update.html")
def chpass(request):
u = request.user
cp = request.POST.get("cpass")
if check_password(cp, u.password):
np = request.POST.get("npass")
u.set_password(np)
u.save()
return redirect("acc:login")
return redirect("acc:update")
def signup(request):
if request.method == "POST":
un = request.POST.get("uname")
up = request.POST.get("upass")
ua = request.POST.get("uage")
uc = request.POST.get("ucomm")
pi = request.FILES.get("upic")
try:
User.objects.create_user(username=un, password=up, age=ua, comment=uc, pic=pi)
return redirect("acc:login")
except:
pass # 메세지
return render(request, "acc/signup.html")
def delete(request):
u = request.user
up = request.POST.get("upass")
if check_password(up, u.password):
u.pic.delete()
u.delete()
return redirect("acc:index")
else:
pass # 메세지
return redirect("acc:profile")
def profile(request):
return render(request, "acc/profile.html")
def ulogout(request):
logout(request)
return redirect("acc:index")
def index(request):
return render(request, "acc/index.html")
def ulogin(request):
if request.user.is_authenticated:
return redirect("acc:index")
if request.method == "POST":
un = request.POST.get("uname")
up = request.POST.get("upass")
u = authenticate(username=un, password=up)
if u:
login(request, u)
return redirect("acc:index")
else:
pass # 메세지
return render(request, "acc/login.html")
|
cs |
- 페이징 기법까지 적용한 전체 코드
7. <board> 앱 생성 > 'models.py'
'models.py'
=====
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
from django.db import models
from acc.models import User
from django.utils import timezone
class Board(models.Model):
subject = models.CharField(max_length=100)
writer = models.ForeignKey(User, on_delete=models.CASCADE, related_name="writer")
content = models.TextField()
pubdate = models.DateTimeField(default=timezone.now)
likey = models.ManyToManyField(User, blank=True, related_name="likey")
def __str__(self):
return self.subject
class Reply(models.Model):
board = models.ForeignKey(Board, on_delete=models.CASCADE)
replyer = models.ForeignKey(User, on_delete=models.CASCADE)
comment = models.TextField()
def __str__(self):
return f"{self.board}_{self.replyer}"
|
cs |
8. <board> > 'admin.py'
'admin.py'
=====
1
2
3
4
|
from django.contrib import admin
from .models import Board, Reply
admin.site.register(Board)
admin.site.register(Reply)
|
cs |
9. <board> > 'urls.py'
'urls.py'
=====
1
2
3
4
5
6
7
8
9
10
11
|
from django.urls import path
from . import views
app_name = "board"
urlpatterns = [
path('index/', views.index, name="index"),
path('detail/<bpk>', views.detail, name="detail"),
path('delete/<bpk>', views.delete, name="delete"),
path('create/', views.create, name="create"),
path('update/<bpk>', views.update, name="update")
]
|
cs |
10. <board> > 'views.py'
'views.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
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
|
from django.shortcuts import render, redirect
from .models import Board
from django.core.paginator import Paginator
def index(request):
pg = request.GET.get("page", 1)
cate = request.GET.get("cate", "")
kw = request.GET.get("kw", "")
if kw:
if cate == "sub":
b = Board.objects.filter(subject__startswith=kw)
elif cate == "wri":
try:
from acc.models import User
u = User.objects.get(username=kw)
b = Board.objects.filter(writer=u)
except:
b = Board.objects.none()
elif cate == "con":
b = Board.objects.filter(content__contains=kw)
else:
b = Board.objects.all()
b = b.order_by("-pubdate")
pag = Paginator(b, 3)
obj = pag.get_page(pg)
context = {
"bset" : obj,
"kw" : kw,
"cate" : cate
}
return render(request, "board/index.html", context)
def update(request, bpk):
b = Board.objects.get(id=bpk)
if request.user != b.writer:
return redirect("board:index")
if request.method == "POST":
s = request.POST.get("sub")
c = request.POST.get("con")
b.subject, b.content = s,c
b.save()
return redirect("board:detail", bpk)
context = {
"b" :b
}
return render(request, "board/update.html", context)
def create(request):
if request.method == "POST":
s = request.POST.get("sub")
c = request.POST.get("con")
Board(subject=s, writer=request.user, content=c).save()
return redirect("board:index")
return render(request, "board/create.html")
def delete(request, bpk):
b = Board.objects.get(id=bpk)
if request.user == b.writer:
b.delete()
else:
pass # 메세지 (불법적인 접근)
return redirect("board:index")
def detail(request, bpk):
b = Board.objects.get(id=bpk)
context = {
"b" : b
}
return render(request, "board/detail.html", context)
|
cs |
- 페이징 기법까지 적용한 전체 코드
11. <templates> > 'base.html'
'base.html'
=====
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
|
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap demo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
</head>
<body>
{% if user.is_authenticated %}
<!-- 인증된 사용자 메뉴바 -->
<nav class="navbar navbar-expand-lg navbar-dark" style="background-color: rgb(0, 0, 0);">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="{% url 'acc:index' %}">HOME</a>
</li>
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="{% url 'board:index' %}">BOARD</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
{{ user }}
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="{% url 'acc:profile' %}">PROFILE</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="{% url 'acc:logout' %}">LOGOUT</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
{% else %}
<!-- 익명의 사용자 메뉴바 -->
<nav class="navbar navbar-expand-lg navbar-dark" style="background-color: rgb(0, 0, 0);">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="{% url 'acc:index' %}">HOME</a>
</li>
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="{% url 'acc:login' %}">LOGIN</a>
</li>
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="{% url 'acc:signup' %}">SIGNUP</a>
</li>
</ul>
</div>
</div>
</nav>
{% endif %}
<div class="container mt-5 mb-5">
{% block con %}
{% endblock %}
</div>
<style>
.nav-item{
font-size: 20px;
font-weight: bold;
margin-left: 10px;
}
.form-control{
font-weight: bold;
font-size: 20px;
}
.form-label{
font-weight: bold;
font-size: 20px;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
</body>
</html>
|
cs |
12. <acc> > 'index.html'
'index.html'
=====
1
2
3
4
5
6
7
8
9
|
{% extends 'base.html' %}
{% block con %}
<div class="p-5 mb-4 bg-light rounded-3">
<div class="container-fluid py-5">
<h1 class="display-5 fw-bold">WELCOME TO MY WEBSITE!</h1>
<p class="col-md-8 fs-4">Hello everyone! My first django project 💥 </p>
</div>
</div>
{% endblock %}
|
cs |
13. <acc> > 'login.html'
'login.html'
=====
1
2
3
4
5
6
7
8
9
10
11
12
|
{% extends 'base.html' %}
{% block con %}
<h1><b>LOGIN PAGE</b></h1>
<form method="post">
{% csrf_token %}
<input type="text" name="uname" class="form-control mt-5" placeholder="INPUT USERNAME">
<input type="password" name="upass" class="form-control mt-3" placeholder="INPUT PASSWORD">
<div class="text-end mt-4">
<button class="btn btn-dark btn-lg">LOGIN</button>
</div>
</form>
{% endblock %}
|
cs |
14. <acc> > 'profile.html'
'profile.html'
=====
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
|
{% extends 'base.html' %}
{% block con %}
<div class="container mt-5 mb-5">
<h1><b>{{ user }}'s PROFILE</b></h1>
<div class="row">
<div class="col-sm-7 text-center" style="margin: auto;">
<img src="{{ user.getpic }}" class="rounded-circle" width="80%">
</div>
<div class="col-sm-5">
<label class="form-label mt-5">USERNAME</label>
<input type="text" value="{{user}}" disabled class="form-control">
<label class="form-label mt-4">AGE</label>
<input type="text" value="{{user.age}}" disabled class="form-control">
<label class="form-label mt-4">EMAIL</label>
<input type="text" value="{{user.email}}" disabled class="form-control">
<label class="form-label mt-4">COMMENT</label>
<textarea class="form-control" style="height:150px" disabled>{{ user.comment }}</textarea>
</div>
</div>
<div class="mt-5 text-end">
<a href="{% url 'acc:update' %}" class="btn btn-dark btn-lg">정보수정</a>
<!-- modal trigger button -->
<button type="button" class="btn btn-danger btn-lg" data-bs-toggle="modal" data-bs-target="#exampleModal">계정삭제</button>
</div>
</div>
<!-- Modal -->
<form method="post" action="{% url 'acc:delete' %}">
{% csrf_token %}
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">계정 삭제 알림창</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<label class="form-label">패스워드 확인</label>
<input type="password" name="upass" class="form-control">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
<button class="btn btn-danger">삭제</button>
</div>
</div>
</div>
</div>
</form>
{% endblock %}
|
cs |
15. <acc> > 'signup.html'
'signup.html'
=====
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
|
{% extends 'base.html' %}
{% block con %}
<h1><b>SIGNUP PAGE</b></h1>
<form method="post" enctype="multipart/form-data" name="createForm">
{% csrf_token %}
<label class="form-label mt-5">USERNAME</label>
<input type="text" name="uname" class="form-control">
<label class="form-label mt-4">PASSWORD</label>
<input type="password" name="upass" class="form-control">
<label class="form-label mt-4">CHECK PASSWORD</label>
<input type="password" name="ckpass" class="form-control">
<label class="form-label mt-4">AGE</label>
<input type="number" value="0" name="uage" class="form-control">
<label class="form-label mt-4">USERPIC</label>
<input type="file" name="upic" class="form-control">
<label class="form-label mt-4">COMMENT</label>
<textarea class="form-control" name="ucomm"></textarea>
<div class="text-end mt-4">
<button type="button" onclick="check()" class="btn btn-dark btn-lg">회원가입</button>
</div>
</form>
<script>
function check(){
cf = document.createForm;
if(!cf.uname.value){
alert("USERNAME 은 필수입력 사항입니다!");
}else if(!cf.upass.value){
alert("PASSWORD 는 필수입력 사항입니다!");
}else if(cf.upass.value != cf.ckpass.value){
alert("PASSWORD 가 서로 일치하지 않습니다 :(");
}else{ cf.submit(); }
}
</script>
{% endblock %}
|
cs |
16. <acc> > 'update.html'
'update.html'
=====
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
|
{% extends 'base.html' %}
{% block con %}
<h1><b>UPDATE PAGE</b></h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<!-- username 은 변경불가하도록 disabled 유지 -->
<label class="form-label mt-5">USERNAME</label>
<input type="text" disabled value="{{user}}" class="form-control">
<label class="form-label mt-4">EMAIL</label>
<input type="text" value="{{user.email}}" name="umail" class="form-control">
<label class="form-label mt-4">USERPIC</label>
<input type="file" class="form-control" name="upic">
<label class="form-label mt-4">COMMENT</label>
<textarea class="form-control" name="ucomm">{{ user.comment }}</textarea>
<div class="text-end mt-4">
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary btn-lg" data-bs-toggle="modal" data-bs-target="#exampleModal">패스워드변경</button>
<button class="btn btn-dark btn-lg">수정완료</button>
</div>
</form>
<!-- Modal -->
<form method="post" action="{% url 'acc:chpass' %}">
{% csrf_token %}
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel"><b>패스워드 변경창</b></h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<input type="password" name="cpass" placeholder="CURRENT PASSWORD" class="form-control">
<input type="password" name="npass" placeholder="NEW PASSWORD" class="form-control mt-3">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
<button class="btn btn-primary">변경</button>
</div>
</div>
</div>
</div>
</form>
{% endblock %}
|
cs |
- 페이징 기법까지 적용한 전체 코드
17. <board> > 'index.html'
'index.html'
=====
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
84
85
86
87
88
89
90
91
|
{% extends 'base.html' %}
{% block con %}
<!-- board/index.html -->
{% load mathfilters %}
<h1><b>게시판</b></h1>
<div class="text-end">
<a href="{% url 'board:create' %}" class="btn btn-dark">게시글생성</a>
</div>
<table class="table table-hover mt-4">
<thead>
<tr class="table-dark">
<th scope="col">NO</th>
<th scope="col">SUBJECT</th>
<th scope="col">SUMMARY</th>
<th scope="col">WRITER</th>
<th scope="col">LIKEY</th>from django.urls import path
</tr>
</thead>
<tbody>
{% for i in bset %}
<tr>
<th scope="row">{{ bset.start_index|add:forloop.counter0 }}</th>
<td><a class="sub" href="{% url 'board:detail' i.id %}">{{ i.subject }}</a></td>
<td>{{ i.content|truncatewords:10 }}</td>
<td>{{ i.writer }}</td>
<td>0</td>
</tr>
{% empty %}
<tr>
{% if kw %}
<th>검색 결과가 존재하지 않습니다 😉</th>
{% else %}
<th>첫 번째 게시글을 작성해주세요 🤣</th>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
<nav aria-label="Page navigation example" class="mt-3">
<ul class="pagination justify-content-center">
{% if bset.has_previous %}
<li class="page-item"><a class="page-link" href="{% url 'board:index' %}?page=1&cate={{cate}}&kw={{kw}}">HOME</a></li>
<li class="page-item"><a class="page-link" href="{% url 'board:index' %}?page={{bset.previous_page_number}}&cate={{cate}}&kw={{kw}}">PRE</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link">HOME</a></li>
<li class="page-item disabled"><a class="page-link">PRE</a></li>
{% endif %}
{% for i in bset.paginator.page_range %}
{% if bset.number|add:3 >= i and i >= bset.number|sub:3 %}
<li class="page-item {% if bset.number == i %} active {% endif %}"><a class="page-link" href="{% url 'board:index' %}?page={{i}}&cate={{cate}}&kw={{kw}}">{{i}}</a></li>
{% endif %}
{% endfor %}
{% if bset.has_next %}
<li class="page-item"><a class="page-link" href="{% url 'board:index' %}?page={{bset.next_page_number}}&cate={{cate}}&kw={{kw}}">NEXT</a></li>
<li class="page-item"><a class="page-link" href="{% url 'board:index' %}?page={{bset.paginator.num_pages}}&cate={{cate}}&kw={{kw}}">FIN</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link">NEXT</a></li>
<li class="page-item disabled"><a class="page-link">FIN</a></li>
{% endif %}
</ul>
</nav>
<form>
<div class="row mt-5">
<div class="col-sm-2">
<select class="form-select" name="cate">
<option value="sub" {% if cate == "sub" %} selected {% endif %}>제목</option>
<option value="wri" {% if cate == "wri" %} selected {% endif %}>작성자</option>
<option value="con" {% if cate == "con" %} selected {% endif %}>내용</option>
</select>
</div>
<div class="col-sm-6">
<input type="text" name="kw" value="{{kw}}" class="form-control">
</div>
<div class="col-sm-2">
<button class="btn btn-secondary" style="width:100%">검색</button>
</div>
<div class="col-sm-2">
<a href="{% url 'board:index' %}"><button class="btn btn-dark" type="button" style="width:100%">초기화</button></a>
</div>
</div>
</form>
{% endblock %}
|
cs |
18. <board> > 'create.html'
'create.html'
=====
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
{% extends 'base.html' %}
{% block con %}
<h1><b>게시글 작성</b></h1>
<form method="post">
{% csrf_token %}
<div class="mb-3 mt-5">
<label class="form-label"><b>SUBJECT</b></label>
<input type="text" name="sub" class="form-control">
</div>
<div class="mb-3">
<label class="form-label"><b>WRITER</b></label>
<input type="text" class="form-control" value="{{ user }}" disabled>
</div>
<div class="mb-3">
<label class="form-label"><b>CONTENT</b></label>
<textarea class="form-control" name="con" style="height: 150px;"></textarea>
</div>
<div class="text-end mt-3">
<button class="btn btn-dark">생성</button>
</div>
</form>
{% endblock %}
|
cs |
19. <board> > 'detail.html'
'detail.html'
=====
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
|
{% extends 'base.html' %}
{% block con %}
<h1><b>{{ b.subject }}</b></h1>
<div class="row mt-5">
<div class="col-sm-9">
<textarea class="form-control" style="height:200px" disabled>{{ b.content }}</textarea>
</div>
<div class="col-sm-3">
<img src="{{ b.writer.getpic }}" width="100%">
<div class="text-center mt-3">
<h5>written by <b>{{ b.writer }}</b></h5>
</div>
<div class="text-end mt-3">
<b>{{ b.pubdate|date:'Y년 m월 d일 / H:i' }}</b>
</div>
</div>
</div>
<div class="text-end mt-4">
<a href="{% url 'board:index' %}" class="btn btn-dark">글목록</a>
{% if user == b.writer %}
<a href="{% url 'board:update' b.id %}" class="btn btn-dark">글수정</a>
<!-- Button trigger modal -->
<button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#remove">
글삭제
</button>
{% endif %}
</div>
<!-- Modal -->
<div class="modal fade" id="remove" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel"><b>게시글 삭제 알림창</b></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
정말 삭제하시겠습니까?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">취소</button>
<a href="{% url 'board:delete' b.id %}" class="btn btn-danger">삭제</a>
</div>
</div>
</div>
</div>
{% endblock %}
|
cs |
20. <board> > 'update.html'
'update.html'
=====
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
{% extends 'base.html' %}
{% block con %}
<h1><b>게시글수정</b></h1>
<form method="post">
{% csrf_token %}
<div class="mb-3 mt-5">
<label class="form-label"><b>SUBJECT</b></label>
<input type="text" value="{{b.subject}}" name="sub" class="form-control">
</div>
<div class="mb-3">
<label class="form-label"><b>WRITER</b></label>
<input type="text" class="form-control" disabled value="{{ b.writer }}">
</div>
<div class="mb-3">
<label class="form-label"><b>CONTENT</b></label>
<textarea class="form-control" name="con" style="height: 150px;">{{ b.content }}</textarea>
</div>
<div class="text-end mt-3">
<button class="btn btn-dark">수정</button>
</div>
</form>
{% endblock %}
|
cs |
'Python_Django' 카테고리의 다른 글
파이선 웹구축_장고_28_검색 필터 설정 (0) | 2023.06.20 |
---|---|
파이선 웹구축_장고_27_검색 옵션 설정 (0) | 2023.06.19 |
파이선 웹구축_장고_25_페이징 페이지 번호 작성 (0) | 2023.06.17 |
파이선 웹구축_장고_24_댓글 선택 삭제 (0) | 2023.06.16 |
파이선 웹구축_장고_23_댓글 등록 (0) | 2023.06.15 |