Django CRUD / 페이징 처리

2017. 8. 21. 16:08· FrameWork/Django
반응형
SMALL

admin 관리창 접속하기(http://hyunchang88.tistory.com/77) 까지 다 했다면


이제 회원정보에 대한 crud 를 해볼거야


Django CRUD (Create, Retrieve, Update, Delete)


장고에선 설정을 잘 하면 table 만드는 것을 알아서 해줘


그걸 하기 위해선 app 을 하나 만들어야해

프로젝트 내에서 하나의 카테고리를 만든다고 보면 됌



Create Application 을 해서



member 하나를 만들어



그럼 프로젝트 하위에 member 패키지가 하나 만들어 진것을 볼 수 있다


(그냥 처음에 만들었을 때는 urls.py 가 없는게 정상 

작업 한 후에 정리중이라 추가 되어 있는 것임....)


Model 설정을 해줘야 해 (테이블을 자동으로 만들어서 관리 할수 있도록)



임포트한 models 를 상속 받아서 정의를 했어


이걸 이용해서 make migration, migrate 하면 이걸 이용해서 테이블이 만들어져


테이블을 정의하려면 칼럼을 정의해놔야해서

칼럼을 코딩 해 놓은 것임


그리고 settings 에 가서



만들어 놓은 member app이 동작하도록 INSTALLED_APPS 에 추가 해 주고


Make Migrations 를 해주면



Create model Member 가 만들어 진것을 확인 가능


그리고 Migrate를 해주면




관리자 창에서 Member 테이블을 확인 할 수 있다.


이제 



views.py 하나 만들어서


1
2
3
4
5
6
7
8
#-*- coding: utf-8 -*-
from django.shortcuts import render
 
def index(request):
    
    # templates/index.html 을 읽어서 출력하도록 
    return render(request, 'index.html')
 
Colored by Color Scripter
cs


이렇게 코딩해 주고



urls.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
#-*- coding: utf-8 -*-
"""Django03_CRUD URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.9/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url, include
from django.contrib import admin
from Django03_CRUD import views
 
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', views.index),
]
 
 
 
Colored by Color Scripter
cs


빈 요청에 대한 응답을 할수 있도록 위와 같이 코댕해줘





templates 하위에 index.html과 member 폴더, member 패키지에 urls.py 를 만들어 준 후


index.html에는 


1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>templates/index.html</title>
</head>
<body>
<h3>인덱스 페이지 입니다.</h3>
<ul>
    <li><a href="/member/list/">회원 목록 보기</a></li>
</ul>
</body>
</html>
Colored by Color Scripter
cs


이렇게 링크 하나 걸어 둬


일단 이렇게만 해주면



이렇게 출력 되는 것을 확인 할 수 있어




urls.py 에


1
2
3
4
5
6
7
8
9
10
11
12
13
14
#-*- coding: utf-8 -*-
 
from django.conf.urls import url
from member import views
 
urlpatterns = [
   url(r'^list/', views.list),
   url(r'^insertform/', views.insertform),
   url(r'^insert/', views.insert),
   url(r'^delete/', views.delete),
   url(r'^updateform/', views.updateform),
   url(r'^update/', views.update),
]
 
Colored by Color Scripter
cs

이렇게 코딩해 주고



member 폴더 하위에도 추가 수정, 삭제를 위해 이렇게 만들어 주고


각각의 소스 코드는


list.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
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>templates/member/list.html</title>
</head>
<body>
<a href="/member/insertform/">회원추가</a>
<h3>회원 목록 입니다.</h3>
<table>
    <thead>
        <tr>
            <th>번호</th>
            <th>이름</th>
            <th>주소</th>
            <th>수정</th>
            <th>삭제</th>
        </tr>
    </thead>
    <tbody>
    {% for item in member_list %}
        <tr>
            <td>{{item.num}}</td>
            <td>{{item.name}}</td>
            <td>{{item.addr}}</td>
            <td><a href="/member/updateform?num={{item.num}}">수정</a></td>
            <td><a href="/member/delete?num={{item.num}}">삭제</a></td>
        </tr>
    {% endfor %}    
    </tbody>
</table>
</body>
</html>
 
Colored by Color Scripter
cs


insert.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>templates/member/insertform.html</title>
</head>
<body>
<h3>회원추가 폼 입니다.</h3>
<form action="/member/insert/" method="post">
    {% csrf_token %}
    <label for="name">이름</label>
    <input type="text" name="name" id="name" />
    <label for="addr">주소</label>
    <input type="text" name="addr" id="addr"/>
    <button type="submit">추가</button>
</form>
</body>
</html>
 
Colored by Color Scripter
cs


updateform.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>templates/member/updateform.html</title>
</head>
<body>
<h3>회원정보 수정 폼 입니다.</h3>
<form action="/member/update/" method="post">
    {% csrf_token %}
    <input type="hidden" name="num" value="{{member.num}}"/>
    <label for="name">이름</label>
    <input type="text" name="name" value="{{member.name}}" />
    <br/>
    <label for="addr">주소</label>
    <input type="text" name="addr" value="{{member.addr}}"/>
    <br/>
    <button type="submit">수정확인</button>
</form>
</body>
</html>
Colored by Color Scripter
cs


alert.html

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>templates/member/alert.html</title>
</head>
<body>
<h3>알림</h3>
<p>{{msg}}</p>
<a href="{{url}}">확인</a>
</body>
</html>
Colored by Color Scripter
cs


이렇게 해주고


member/ 로 시작하는 요청은 member.urls 에서 처리를 하겠다고 선언을 해 줘야해


여기서


이렇게 코딩을 해주면


member/ 로 시작하는 요청은 member.urls 에서 처리를 하겠다고 선언을 한 것이 됌



이것들을 동작 시키기 위해선



meber 패키지 하위의 urls와 views 에 코딩을 해 줘야 한다.


urls.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#-*- coding: utf-8 -*-
 
from django.conf.urls import url
from member import views
 
urlpatterns = [
   url(r'^list/', views.list),
   url(r'^insertform/', views.insertform),
   url(r'^insert/', views.insert),
   url(r'^delete/', views.delete),
   url(r'^updateform/', views.updateform),
   url(r'^update/', views.update),
]
 
Colored by Color Scripter
cs


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
#-*- coding: utf-8 -*-
from django.shortcuts import render
from member.models import Member
from django.http.response import HttpResponseRedirect
 
# Create your views here.
 
def list(request):
    # Member 모델의 모든 데이터를 가지고 온다 
    member_list=Member.objects.all().order_by('num')
    return render(
        request, 
        'member/list.html', # templates/member/list.html 
        {'member_list':member_list},         
    )
 
# 회원 추가 폼 요청 처리 
def insertform(request):
    return render(request, 'member/insertform.html')
 
# 회원정보 추가 요청 처리 
def insert(request):
    # post 방식 전송 되기 위해서는 form 안에 {% csrf_token %} 작성
    # post 방식 전송되는 파리미터 추출해서  Member 모델 객체 생성
    mem=Member(
        name=request.POST.get("name"),
        addr=request.POST.get("addr"),
    )
    # DB 에 반영
    mem.save()
    # 리다일렉트 이동하라고 응답 
    return HttpResponseRedirect('/member/list/')
 
def delete(request):
    # get 방식 전달되는  삭제할 번호 얻어오기
    # num = request.GET.get("num") 
    # 삭제하기 
    # mem=Member.objects.get(num=num)
    # mem.delete()
    
    # 위의 작업을 한줄로 표현하면 ...
    Member.objects.get(num=request.GET.get("num")).delete()
    
    #return HttpResponseRedirect("/member/list/")
    return render(
        request,
        'member/alert.html',
        {
            "msg":u"삭제 했습니다.",
            "url":"/member/list/"
        },
    )
 
# 회원정보 수정 form 처리 
def updateform(request):
    # get 방식 전달된 수정할 회원의 번호를 이용해서 회원정보를 얻어온다.
    member=Member.objects.get(num=request.GET.get("num"))
    # member 는 dict type 이다. 
    return render(
        request,
        'member/updateform.html',
        {"member":member},
    )
 
def update(request):
    member=Member(
      num=request.POST.get("num"),
      name=request.POST.get("name"),
      addr=request.POST.get("addr"),  
    )
    # .save() 메소드는 data 가 있으면 수정 반영, 없으면 insert
    member.save()
    return render(
        request,
        'member/alert.html',
        {"msg":u"수정했습니다.", "url":"/member/list/"},
    )
 
 
Colored by Color Scripter
cs


이렇게 코딩을 해주면


어떤 요청 처리가 들어 왔을때

어떤 메소드로 처리를 하겠다고 쭉 코딩이 된 것임


수정 반영을 할때

내가 응답한 것을 받아서 수정 요청을 하는지 다른거에 대해 요청을 받아서 수정 요청을 하는지 구분을 해야해

그걸 csrf 토큰 이라는 것으로 하는데


insertform.html 에서



{% csrf_token %} 이걸 코딩해주면



뭔가 자기가 알아서 판단할 수 있게 token 을 만든 것을 볼수 있어



이제 실행시켜서 추가, 수정, 삭제를 해보면



잘 동작하는 것을 확인 할 수 있다.




페이징 처리


여기에 페이징 처리를 추가로 해볼거야



빨간 밑줄은 startPageNum-1 의미


페이징 처리를 하기 위해선 산술 연산을 써야하는데 


파이썬에선 산술연산이 안되서


mathfilters 를 설치 해야해



명령 프롬프트창 열어서 


pip install django-mathfilters 입력해주면 


mathfilters 가 설치 된 것임



확인 가능


settings.py 들어가서




INSTALLED_APPS 에


mathfilters 를 추가해 주고


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
def list(request):
    
    PAGE_ROW_COUNT=5
    PAGE_DISPLAY_COUNT=5
    
    total_list=Member.objects.all().order_by('-num')
    
    paginator=Paginator(total_list, PAGE_ROW_COUNT)
    pageNum=request.GET.get('pageNum')
    
    totalPageCount=paginator.num_pages # 전체 페이지 갯수 
    
    try:
        member_list=paginator.page(pageNum)
    except PageNotAnInteger:
        member_list=paginator.page(1)
        pageNum=1
    except EmptyPage:
        member_list=paginator.page(paginator.num_pages)
        pageNum=paginator.num_pages
        
    pageNum=int(pageNum)
    
    startPageNum=1+((pageNum-1)/PAGE_DISPLAY_COUNT)*PAGE_DISPLAY_COUNT
    endPageNum=startPageNum+PAGE_DISPLAY_COUNT-1
    if totalPageCount < endPageNum:
        endPageNum=totalPageCount
        
    bottomPages=range(startPageNum, endPageNum+1)
    
    return render(
        request,
        'member/list.html', 
        {
            'member_list':member_list,
            'pageNum':pageNum,
            'bottomPages':bottomPages,
            'totalPageCount':totalPageCount,
            'startPageNum':startPageNum,
            'endPageNum':endPageNum
        }
    )
 
 
Colored by Color Scripter
cs


이거 추가해 주고



list.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
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>member/list.html</title>
<style>
    .page_display a{
        text-decoration:none;
        color: #000;
    }
    .page_display a.active{
        font-weight: bold;
        color: red;
        text-decoration: underline;
    }
    .page_display a.muted{
        color:#cecece;
    }
</style>
</head>
<body>
<a href="/member/insertform">회원추가</a>
<h3>회원 목록입니다.</h3>
<table>
    <thead>
        <tr>
            <th>번호</th>
            <th>이름</th>
            <th>주소</th>
            <th>수정</th>
            <th>삭제</th>
        </tr>
    </thead>
    <tbody>
        {% for item in member_list %}
        <tr>
            <td>{{item.num}}</td>
            <td>{{item.name}}</td>
            <td>{{item.addr}}</td>
            <td><a href="/member/updateform?num={{item.num}}">수정</a></td>
            <td><a href="/member/delete?num={{item.num}}">삭제</a></td>
        </tr>
        {% endfor%}
    </tbody>
</table>
<div class="page_display">
    <!-- 
        mathfilters 를 사용하려면
        1. pip install django-mathfilters
        2. settings.py 에 INSTALLED_APPS 에 'mathfilters' 추가
        3. 아래에 로딩 표현식 추가
     -->
    {% load mathfilters %}
 
    {% if startPageNum != 1 %}
        <a href="/member/list?pageNum={{startPageNum | sub:1}}">[이전]</a>
    {% else %}
        <a href="javascript:" class="muted">[이전]</a>
    {% endif %}
    
    {% for i in bottomPages %}
        {% if i == pageNum %}
            <a class="active" href="/member/list?pageNum={{i }}">{{i }}</a>
        {% else %}
            <a href="/member/list?pageNum={{i }}">{{i }}</a>
        {% endif %}
    {% endfor %}
    
    {% if endPageNum < totalPageCount %}
        <a href="/member/list?pageNum={{endPageNum | add:1}}">[다음]</a>
    {% else %}
        <a href="javascript:" class="muted">[다음]</a>
    {% endif %}
</div>
</body>
</html>
 
Colored by Color Scripter
cs


코드를 추가해줘



실행 시켜보면 뭔가 됐어


잘 동작하는지 확인 하기 위해 데이터들을 더 추가해주면



잘 처리 된 것을 확인 가능하다








반응형

'FrameWork > Django' 카테고리의 다른 글

Django block title / block content / include  (2) 2017.08.22
Django Json  (0) 2017.08.22
Django admin 관리창 접속하기  (0) 2017.08.21
Django01  (0) 2017.08.19
Django 설치  (0) 2017.08.19
'FrameWork/Django' 카테고리의 다른 글
  • Django block title / block content / include
  • Django Json
  • Django admin 관리창 접속하기
  • Django01
- 광속거북이 -
- 광속거북이 -
IT관련 일하면서 공부 및 일상 에 관한 내용들을 기록하기 위한 블로그 입니다.
누리IT관련 일하면서 공부 및 일상 에 관한 내용들을 기록하기 위한 블로그 입니다.
- 광속거북이 -
누리
- 광속거북이 -
전체
오늘
어제
  • 카테고리 (450) N
    • 구글문서 (4)
    • 설치방법들 (3)
    • FrameWork (73)
      • Django (6)
      • Python (32)
      • AngularJS (13)
      • spring (21)
    • Programing (14)
      • JAVA (11)
      • etc... (2)
      • 오류 해결 (29)
      • Algorithm (5)
    • Front-End (25)
      • CSS (3)
      • html (6)
      • javascript (10)
      • vueJS (5)
    • Back-End (4) N
      • 리눅스 (12)
      • PostgreSQL (14)
      • MySQL (2)
      • Shell (1)
      • docker (1)
      • GIT (1)
    • Util (9)
      • BIRT (2)
      • JMeter (3)
      • MobaXterm Personal (1)
      • ClipReport (2)
    • 이클립스 설정 (10)
      • SVN (1)
    • 업무중 기록해둘 것들... (1)
    • 영화 (8)
    • etc.. (196)
      • 여행 (25)
      • 문화생활 (3)
      • tistory (3)
      • 글, 생각 (4)
      • 먹을 곳 (29)
      • issue (4)
      • 결혼 (1)
      • 가족여행기록 (1)
      • Tip (49)
      • 강아지 (5)
      • 일기 (0)
      • 게임 (3)
      • 주식 (7)
      • 코로나19 (7)
      • 맥북 (5)

블로그 메뉴

  • 홈
  • 태그
  • 미디어로그
  • 위치로그
  • 방명록

공지사항

인기 글

태그

  • Java
  • tomcat
  • 맛집
  • PostgreSQL
  • 포켓몬고
  • 설치
  • VSCode
  • 이클립스
  • 합정
  • 윈도우10
  • 백준
  • IntelliJ
  • 리눅스
  • 인텔리제이
  • target
  • 연천
  • 해지
  • 카페
  • 제주도
  • 삼성증권

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
- 광속거북이 -
Django CRUD / 페이징 처리
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.