프로젝트 생성 과정
-기존 db 연동하기
anaconda prompt
python manage.py inspectdb > abc.py
type abc.py
생성된 abc.py에서 sangdata class 복사해서 models에 붙여넣기
사용을 다 한 abc.py는 삭제
urls 작성
views 함수 작성, import MySQLdb, config 작성
templates 작성
프로젝트 예시 코드
settings.py
"""
Django settings for django8_sangdata project.
Generated by 'django-admin startproject' using Django 4.1.2.
For more information on this file, see
https://docs.djangoproject.com/en/4.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.1/ref/settings/
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-h%7@pzbm%gp__aqhf!o)px88u1uf9+a+!yj8@2mn7f&80z+p&h"
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"mysangpum",
]
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 = "django8_sangdata.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"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 = "django8_sangdata.wsgi.application"
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test', # DB명 : db는 미리 작성되어 있어야 함.
'USER': 'root', # 계정명
'PASSWORD': '123', # 계정 암호
'HOST': '127.0.0.1', # DB가 설치된 컴의 ip
'PORT': '3306', # DBMS의 port 번호
}
}
# Password validation
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
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",},
]
# Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/
STATIC_URL = "static/"
# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
models.py
from django.db import models
# Create your models here.
class Sangdata(models.Model):
code = models.IntegerField(primary_key=True)
sang = models.CharField(max_length=20, blank=True, null=True)
su = models.IntegerField(blank=True, null=True)
dan = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'sangdata'
urls.py
from django.contrib import admin
from django.urls import path
from mysangpum import views
from django.urls.conf import include
urlpatterns = [
path("admin/", admin.site.urls),
path('',views.MainFunc),
path('sangpum/', include('mysangpum.urls'))
]
urls.py (mysangpum)
from django.urls import path
from mysangpum import views
urlpatterns = [
path('list', views.ListFunc),
path('insert', views.InsertFunc),
path('insertok', views.InsertOkFunc),
path('update', views.UpdateFunc),
path('updateok', views.UpdateOkFunc),
path('delete', views.DeleteFunc),
]
views.py
from django.shortcuts import render
import MySQLdb
from mysangpum.models import Sangdata
from django.http.response import HttpResponseRedirect
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
# sangdata table과 연동
config = {
'host':'127.0.0.1',
'user':'root',
'password':'123',
'database':'test',
'port':3306,
'charset':'utf8',
'use_unicode':True
}
# Create your views here.
def MainFunc(request):
return render(request, 'main.html')
def ListFunc(request):
# SQL문 직접 사용 # 반환 : tuple
"""
sql = 'select * from sangdata'
conn = MySQLdb.connect(**config)
cursor = conn.cursor()
cursor.execute(sql)
datas = cursor.fetchall()
print(datas, type(datas))
"""
# ORM # 반환 : QuerySet
"""
datas = Sangdata.objects.all()
"""
"""
return render(request, 'list.html', {'sangpums':datas})
"""
# 내림차순, 페이지 나누기
datas = Sangdata.objects.all().order_by('-code')
paginator = Paginator(datas, 5)
try:
page = request.GET.get('page')
except:
# 넘어온 page 값이 없다면 1페이지로 시작
page = 1
try:
# page에 해당되는 자료를 읽기
data = paginator.page(page)
except PageNotAnInteger:
data = paginator.page(1)
except EmptyPage:
data = paginator.page(paginator.num_pages())
# 낱개 페이지 번호를 출력한다면 ...
allpage = range(paginator.num_pages + 1) # (0, 4 + 1)
return render(request, 'list2.html', {'sangpums':data, 'allpage':allpage})
def InsertFunc(request):
return render(request, 'insert.html')
def InsertOkFunc(request):
if request.method == 'POST':
# 신상품 code 등록 여부 판단
try:
Sangdata.objects.get(code=request.POST.get('code'))
return render(request, 'insert.html', {'msg':'이미 등록된 code 입니다.'})
except Exception as e:
# 입력 자료의 code가 등록된 숫자가 아니므로 insert 작업을 진행
Sangdata(
code=request.POST.get('code'),
sang=request.POST.get('sang'),
su=request.POST.get('su'),
dan=request.POST.get('dan'),
).save()
return HttpResponseRedirect("/sangpum/list") # 추가 후 목록보기
def UpdateFunc(request):
data = Sangdata.objects.get(code=request.GET.get('code'))
return render(request, 'update.html', {'sang_one':data})
def UpdateOkFunc(request):
if request.method == 'POST':
upRec = Sangdata.objects.get(code=request.POST.get('code'))
upRec.code = request.POST.get('code')
upRec.sang = request.POST.get('sang')
upRec.su = request.POST.get('su')
upRec.dan = request.POST.get('dan')
upRec.save()
return HttpResponseRedirect("/sangpum/list") # 수정 후 목록보기
def DeleteFunc(request):
delRec = Sangdata.objects.get(code=request.GET.get('code'))
delRec.delete()
return HttpResponseRedirect("/sangpum/list") # 삭제 후 목록보기
main.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
메인 페이지<p/>
직원 고객 부서 <a href="sangpum/list">상품</a>
</body>
</html>
list.html - 사용하지 않았다.
페이징 처리 없는 표, 예시에서는 주석처리하고 사용하지 않았다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
** 상품 정보 **<p/>
<div style="width:80%; text-align:right;">
<a href="/sangpum/insert">상품 추가</a>
</div>
<table border="1" style="width:80%">
<tr style="background-color: orange">
<th>코드</th><th>상품명</th><th>수량</th><th>단가</th><th>기타</th>
</tr>
{% if sangpums %}
{% for s in sangpums %}
<tr>
<!-- select문의 결과를 출력할 때는 tuple 이므로 s.0,..사용 -->
<td>{{s.code}}</td>
<td>{{s.sang}}</td>
<td>{{s.su}}</td>
<td>{{s.dan}}</td>
<td>
<a href="/sangpum/update?code={{s.code}}">수정</a>
<a href="/sangpum/delete?code={{s.code}}">삭제</a>
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="5">자료 없음</td>
</tr>
{% endif %}
</table>
</body>
</html>
list2.html
페이징 처리가 된 표
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function func(arg){
//alert(arg);
let result = confirm("정말 삭제할까요?");
if(result){
document.getElementById(arg).submit();
}
}
</script>
</head>
<body>
** 상품 정보 **<p/>
<div style="width:80%; text-align:right;">
<a href="/sangpum/insert">상품 추가</a>
</div>
<table border="1" style="width:80%">
<tr style="background-color: orange">
<th>코드</th><th>상품명</th><th>수량</th><th>단가</th><th>기타</th>
</tr>
{% if sangpums %}
{% for s in sangpums %}
<tr>
<!-- select문의 결과를 출력할 때는 tuple 이므로 s.0,..사용 -->
<td>{{s.code}}</td>
<td>{{s.sang}}</td>
<td>{{s.su}}</td>
<td>{{s.dan}}</td>
<td>
<a href="/sangpum/update?code={{s.code}}">수정</a> /
<!-- 삭제 확인 메시지를 못보여준다
<a href="/sangpum/delete?code={{s.code}}">삭제</a>
-->
<form action="/sangpum/delete" name="frm" method="get"
id ="{{s.code}}" style="display: inline">
<input type="hidden" name="code" value="{{s.code}}">
<a href="javascript:void(0); onclick=func({{s.code}})">삭제</a>
</form>
</td>
</tr>
{% endfor %}
<!-- 페이징 처리 -->
<tr>
<td colspan="5">
{% if sangpums.paginator.num_pages > 1 %}
<div>
{% if sangpums.has_previous %}
<a href="/sangpum/list?page={{sangpums.previous_page_number}}">«이전</a>
{% endif %}
{% if sangpums.has_next %}
<a href="/sangpum/list?page={{sangpums.next_page_number}}">다음»</a>
{% endif %}
(페이지:{{sangpums.number}} / {{sangpums.paginator.num_pages}})
<hr>
{% for p in allpage %}
{% if p > 0 %}
{% if p == sangpums.number %} <!-- 현재 페이지는 링크에서 제외 -->
[{{p}}]
{% else %}
<a href="/sangpum/list?page={{p}}">[{{p}}]</a>
{% endif %}
{% endif %}
{% endfor %}
</div>
{% endif %}
</td>
</tr>
{% else %}
<tr>
<td colspan="5">자료 없음</td>
</tr>
{% endif %}
</table>
</body>
</html>
insert.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
window.onload = function(){
document.querySelector("#btnSubmit").onclick = function(){
chkData();
}
}
function chkData(){
// alert('a');
if(frm.code.value === "" || frm.sang.value === ""){
alert("입력자료를 모두 채우시오");
return;
}
// su, dan은 생략
frm.submit();
}
</script>
</head>
<body>
<h3>* 상품 추가 *</h3>
<form action="/sangpum/insertok" name="frm" method="post">{% csrf_token %}
<table style="width:80%">
<tr>
<td>코드 : </td>
<td><input type="text" name="code"><span style="color:red">{{msg}}</span></td>
</tr>
<tr>
<td>품명 : </td>
<td><input type="text" name="sang"></td>
</tr>
<tr>
<td>수량 : </td>
<td><input type="text" name="su"></td>
</tr>
<tr>
<td>단가 : </td>
<td><input type="text" name="dan"></td>
</tr>
<tr>
<td colspan="2">
<input type="button" value="저장" id="btnSubmit">
</td>
</tr>
</table>
</form>
</body>
</html>
update.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>* 상품 수정 *</h2>
<form action="/sangpum/updateok" method="post">{% csrf_token %}
<input type="hidden" name="code" value="{{sang_one.code}}">
<table style="width:80%">
<tr>
<td>코드 : </td>
<td>{{sang_one.code}}</td>
</tr>
<tr>
<td>품명 : </td>
<td><input type="text" name="sang" value="{{sang_one.sang}}"></td>
</tr>
<tr>
<td>수량 : </td>
<td><input type="text" name="su" value="{{sang_one.su}}"></td>
</tr>
<tr>
<td>단가 : </td>
<td><input type="text" name="dan" value="{{sang_one.dan}}"></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="수정하기">
<input type="button" value="이전화면" onclick="history.back()">
</td>
</tr>
</table>
</form>
</body>
</html>
'Django' 카테고리의 다른 글
django9 - DB, 게시판, 댓글 (0) | 2022.10.19 |
---|---|
django project 과정 정리 (0) | 2022.10.18 |
django7 - DB, multi-table (제조사, 상품 관리) (0) | 2022.10.18 |
django6 - Maria DB (방명록) (0) | 2022.10.17 |
django5 - DB (0) | 2022.10.17 |