goodthings4me.tistory.com
파이썬 장고(django)로 웹 기반 주소록을 만들어보는 유튜브 영상을 간단하게 정리한 내용이다. VS Code에서 가상환경을 만들고, 장고를 설치한 후 앱(address)을 만들어서 웹 페이지에 띄우는 방법을 설명한다.
장고(django) 기반 주소록 웹 페이지 만들어보기
[가상환경 등 만들고 장고 프로젝트 생성 및 초기 설정하기]
D:\workspace\myDjango\myweb>python -V
Python 3.10.4
D:\workspace\myDjango\myweb>python -m venv venv
D:\workspace\myDjango\myweb>cd venv\Scripts
D:\workspace\myDjango\myweb\venv\Scripts>activate
(venv) D:\workspace\myDjango\myweb\venv\Scripts>cd..
(venv) D:\workspace\myDjango\myweb\venv>cd..
(venv) D:\workspace\myDjango\myweb>pip install django==3.2
(venv) D:\workspace\myDjango\myweb>python -m pip install --upgrade pip
(venv) D:\workspace\myDjango\myweb>django-admin startproject config .
(venv) D:\workspace\myDjango\myweb>django-admin startapp address
(venv) D:\workspace\myDjango\myweb>python manage.py migrate
(venv) D:\workspace\myDjango\myweb>python manage.py createsuperuser
Username (leave blank to use 'vsc24'): admin
Email address:
Password:
Password (again):
Superuser created successfully.
(venv) D:\workspace\myDjango\myweb>python manage.py startapp address
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'address',
]
LANGUAGE_CODE = 'ko' #'en-us' # ko-kr에서 ko로 변경됨
TIME_ZONE = 'Asia/seoul' #'UTC'
- D:\workspace\myDjango 폴더에 myweb이라는 프로젝트 폴더를 만들고 VS Code 에서 폴더 열기로 해당 디렉터리를 오픈한다.
- python -m venv venv 명령으로 가상환경을 만들고, 가상환경으로 진입한 후
- 장고 설치(버전 3.2) 후 장고 프로젝트 및 앱 생성 후 필요한 기본 앱 db 생성을 위해 migrate 명령 실행
- 관리자 계정 생성 (이메일은 생략 가능) : python manage.py createsuperuser
- settings.py에 앱(address) 등록
- 웹 서버 구동 언어와 로컬 시간 설정
# python manage.py makemigrations # 변경사항 수집
# python manage.py migrate # 변경사항 적용 / db.sqlite3 생성
[장고 models 활용하여 테이블 만들기]
from pyexpat import model
from django.db import models
class Address(models.Model):
idx = models.AutoField(primary_key=True)
name = models.CharField(max_length=50, blank=True, null=True)
tel = models.CharField(max_length=50, blank=True, null=True)
email = models.CharField(max_length=50, blank=True, null=True)
address = models.CharField(max_length=500, blank=True, null=True)
[models 마이그레이션 하기]
(venv) D:\workspace\myDjango\myweb>python manage.py makemigrations
Migrations for 'address':
address\migrations\0001_initial.py
- Create model Address
(venv) D:\workspace\myDjango\myweb>python manage.py migrate
Operations to perform:
Apply all migrations: address, admin, auth, contenttypes, sessions
Running migrations:
Applying address.0001_initial... OK
(venv) D:\workspace\myDjango\myweb>
# 생성된 테이블 이름은 "앱이름_models.클래스명"
[models를 admin에 등록하기]
from django.contrib import admin
from address.models import Address
class AddressAdmin(admin.ModelAdmin):
# 화면에 출력할 필드(models.Address 변수) 목록을 튜플로 지정
list_display = ('name', 'tel', 'email', 'address')
admin.site.register(Address, AddressAdmin)
# 테이블 만들기는 위 처럼 models.py, admin.py를 수정하여 만든다.
# models.py는 sqlite3 db 테이블에 대한 모델 클래스를 정의 (ORM)하는 모듈이며, django.db.models.Model 클래스를 상속받는다.
- 클래스 : 테이블
- 클래스의 변수 : 컬럼
# admin.py는 models.py에 등록한 테이블이 Admin 사이트에서 보이도록 처리하는 모듈임 (사이트 관리 기능)
# 생성된 테이블 구조
CREATE TABLE "address_address" ("idx" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(50) NULL, "tel" varchar(50) NULL, "email" varchar(50) NULL, "address" varchar(500) NULL)
# myweb Tree 확인

추가적으로 생성하는 폴더 및 모듈, 그리고 템플릿 엔진에 필요한 html 파일들을 살펴보면,
config/
- views.py 모듈은 없어도 되나 여기서는 urls.py에서 웹 서비스 80 포트로 접속하면 views.home을 호출하고 home()에서 웹 페이지의 디폴트(메인) 화면인 index.html을 불러오도록 만들었다.
- 그리고, address/로 접속할 경우 address/urls.py로 가도록 path()에 지정함
address/ (주소록 앱)
- urls.py 모듈 파일을 만들고, 접속 URL에 따라 views.py 모듈로 분기 처리
- 장고 템플릿 생성을 위해 폴더(templates 폴더와 그 하위에 address 폴더)를 만들고 서비스에 필요한 html 파일들을 생성함
이후 코드들에 대한 설명
아래의 코드 내용들은 주소록 서비스를 위해 필요한 모듈들의 소스 코드이며, 웹페이지 화면을 생성하면서 하나씩 순서대로 완성을 해야하는 것들임
[config/urls.py]
from django.contrib import admin
from django.urls import path, include
from config import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.home),
path('address/', include('address.urls')),
]
[config/views.py]
from django.shortcuts import render
def home(request):
# html code tempalte 위치 : address/templates/index.html
return render(request, 'index.html')
[address/urls.py]
from unicodedata import name
from django.urls import path
from address import views
app_name = 'board'
urlpatterns = [
path('', views.home),
path('write/', views.write, name='write'),
path('insert/', views.insert, name='insert'),
path('detail/', views.detail, name='detail'),
path('update/', views.update, name='update'),
path('delete/', views.delete, name='delete'),
]
- 영상 내용에는 없지만, 앱이름과 각 URL 이름을 지정하여 html 파일에서 URLConf가 쉽게 링크되도록 함
[address/views.py]
from ast import Add
from django.shortcuts import render, redirect
from address.models import Address
def home(request):
items = Address.objects.order_by('-idx')
return render(request, 'address/list.html', {'items': items, 'address_count': len(items)})
def write(request):
return render(request, 'address/write.html')
def insert(request):
# 폼에 입력한 값들이 request에 저장됨
# request.POST['변수명']은 post 방식으로 전달된 데이터
# request.GET['변수명']은 get 방식으로 전달된 데이터
addr = Address(name=request.POST['name'], tel=request.POST['tel'], email=request.POST['email'], address=request.POST['address'])
addr.save() # 폼 입력값을 db table에 저장 (레코드, row 단위로)
return redirect('/address')
def detail(request):
id = request.GET['idx']
addr = Address.objects.get(idx=id)
return render(request, 'address/detail.html', {'addr': addr})
def update(request):
id = request.POST['idx']
addr = Address(idx=id, name=request.POST['name'], tel=request.POST['tel'], email=request.POST['email'], address=request.POST['address'])
addr.save() # 수정된 폼 입력값을 db table에 저장
return redirect('/address/')
def delete(request):
id = request.POST['idx']
addr = Address.objects.get(idx=id)
addr.delete()
return redirect('/address/')
- 영상 내용에 update()와 delete() 내용이 없어서 직접 작성함
[index.html]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Index</title>
</head>
<body>
<h2>주소록 관리 홈</h2>
<hr>
<a href="/address">주소록</a><br>
</body>
</html>
- 메인화면에서 주소록 메뉴로 진입하도록 링크 부여

[list.html]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>List</title>
</head>
<body>
<h2>주소록</h2>
<hr>
<a href="/">Home</a>
<a href="{% url 'board:write' %}">등록</a>
<hr>
[등록된 주소 : {{ address_count }}]<br>
<table border="1">
<tr>
<th>번호</th>
<th>이름</th>
<th>전화번호</th>
<th>이메일</th>
<th>주소</th>
</tr>
{% for row in items %}
<tr>
<td>{{ forloop.revcounter }}</td>
<td><a href="detail?idx={{ row.idx }}">{{ row.name }}</a></td>
<td>{{ row.tel }}</td>
<td>{{ row.email }}</td>
<td>{{ row.address }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
- urls.py에서 path() 내에 <int:pk>로 받는 부분을 url 파라미터인 ?dix= 로 처리함

[write.html]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Write</title>
</head>
<body>
<h2>주소록 등록</h2>
<hr>
<form method="post" action="{% url 'board:insert' %}">
{% csrf_token %} <!-- csrf : Cross Site Request Forgery -->
이름 : <input name="name"><br>
전화번호 : <input name="tel"><br>
이메일 : <input name="email"><br>
주소 : <input name="address"><br>
<input type="submit" value="등록">
</form>
</body>
</html>

[detail.html]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Detail</title>
<script>
function update() {
document.form1.action = "{% url 'board:update' %}";
document.form1.submit()
}
function del() {
document.form1.action = "{% url 'board:delete' %}";
document.form1.submit()
}
</script>
</head>
<body>
<h2>주소록 세부 내용</h2>
<hr>
<form name="form1" method="post">
{% csrf_token %}
<table border="1">
<tr>
<td>이름</td>
<td><input name="name" value="{{ addr.name }}"></td>
</tr>
<tr>
<td>전화번호</td>
<td><input name="tel" value="{{ addr.tel }}"></td>
</tr>
<tr>
<td>이메일</td>
<td><input name="email" value="{{ addr.email }}"></td>
</tr>
<tr>
<td>주소</td>
<td><input name="address" value="{{ addr.address }}"></td>
</tr>
<tr>
<td colspan="2">
<input type="hidden" name="idx" value="{{ addr.idx }}">
<input type="button" value="수정" onclick="update()">
<input type="button" value="삭제" onclick="del()">
</td>
</tr>
</table>
</form>
</body>
</html>
- form action 부분(수정, 삭제 부분의 submit)을 자바스크립트 함수로 처리

[참고(출처)영상] : Django의 개요, 설치, 주소록 만들기
블로그 인기글
유튜브 영상 등의 URL 주소를 QR코드로 만들기
네이버 QR코드, makeQR, MUST QRcode, 무료 온라인 QRCode 생성기 등의 웹사이트에서 유튜브 영상 등의 URL을 입력하여 QR코드를 만들 수 있다. QR코드를 생성할 수 있는 사이트와 프로그램 URL 주소를 붙여넣기 한 후 "QR 코드 생성" 버튼을 클릭하면 큐알코드가 이미지로 생성되고, 다운로드도 할 수 있는 사이트 https://truedoum.com/useful/qrcode/ # 유튜브에서 동영상 URL을 복사하는 방법 유튜브에서 QR코드를 만들 동영상을 검색한다. 해당 동영상을 클릭한다. 동영상 위에서 마우스 우클릭 후 나오는 팝업창에서 “동영상 URL 복사”를 클릭하거나 영상 하단의 “공유”를 클릭하여 나온 창에서 URL를 복사한다. 아래의 웹사이트 중 하나를 선택한 후 복사..
goodthings4me.tistory.com
Windows 10 탐색기 느려지는 증상과 해결하는 방법
잘 작동하던 Windows 10 탐색기가 갑자기 느려지는 증상이 발생했을 때 어떻게 조치를 하는지 구글에서 찾아보니 많은 해결책들이 있었으나 어떤 것이 정확한 해결책인지는 알 수가 없었다. 그래서 해결방법이라고 제시한 것들을 정리해 보았다. 윈도우 탐색기가 느려지는 증상 해결 방법 어느 순간부터 응용프로그램(VS Code 등)에서 폴더 열기나 파일 불러오기를 했을 때 검색 팝업창이 안 뜨거나 열리는 시간이 엄청 느려지는 증상과, 더불어서 탐색기도 실행이 많이 느려지는 증상이 있었다. 기존에 사용하던 VS Code에 openpyxl 설치 후 실행이 느려지는 증상이 발생하더니 윈도우10 탐색기도 느려져서 사용할 수가 없었다. 노트북에 OS(Windows10)를 설치한지 1년이 다 되어가긴 했지만, 1개월 전..
goodthings4me.tistory.com
[국세청] 현금영수증가맹점으로 가입바랍니다. 메시지 해결방법(개인사업자)
▶ 현금영수증 가맹점 가입 메시지를 받고... 온라인 쇼핑몰 사업을 시작하려고 사업자등록증을 발급받고 난 후 얼마 안 있어서 국세청으로부터 어느 시점까지 '현금영수증 가맹점'으로 가입하라는 문자메시지가 받았었다. 그 메시지 기한이 오늘 도래했는데, 인터넷에서 찾아보니 홈택스에서 현금영수증 발급 사업자 신청을 할 수가 있었다. [관련내용] 홈>국세정책/제도>전자(세금)계산서/현금영수증/신용카드>현금영수증∙신용카드>가맹점가입 ▶ 홈택스 사이트에서 신청하는 절차는 다음과 같다. 우선, 홈택스에 로그인을 해야 합니다. 세상이 좋아져서 공인인증서 없이도 손쉽게 간편인증 로그인이 가능하다. 여러 인증방법 중 카카오톡 인증이 가장 편리한 거 같다. 간편인증 로그인 후 상단 '조회/발급' 탭 클릭 후 '현금영수증>현금..
goodthings4me.tistory.com
'코딩 연습' 카테고리의 다른 글
파이썬 장고에서 db table에 직접 접속하는 파일(.py) 만들기 (0) | 2022.06.23 |
---|---|
짧은 주소(단축URL) 만들기 (0) | 2022.06.21 |
웹 브라우저 새로고침(F5) 시 데이터 전송 안 되게 하는 문제 (0) | 2022.06.16 |
파이썬 os 모듈(os 또는 os.path)과 pathlib 모듈 비교 (0) | 2022.06.06 |
파이썬 클래스 연습 - 게임 아이템의 종류 구입, 사용, 버리기 메서드 (0) | 2022.06.05 |
댓글