본문 바로가기
코딩 연습

파이썬 장고로 주소록 만들기 [장고 기초 예제]

by good4me 2022. 6. 17.

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  생성

 

good4me.co.kr

 

[장고 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의 개요, 설치, 주소록 만들기

 

 

댓글