DEVELOP
article thumbnail

Django 설치 및 포트 접속 

$ pip install django
$ django-admin startproject project-name
$ cd project-name
$ python manage.py runserver
$ django-admin startapp myapp

 - 127.0.0.1:8000 접속 후 아래 화면 뜨면 포트 접속 성공 

- 포트 번호 직접 지정 가능 

$ python manage.py runserver 8888

라우팅

- 어떤 프레임워크를 쓰더라도 라우팅이 가장 중요 

- myproject/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('myapp.urls'))
]

- myapp/urls.py

from django.contrib import admin
from django.urls import path
from myapp import views

urlpatterns = [
    path('', views.index),
    path('create/', views.create),
    path('read/<id>',views.read),
]

- myapp/views.py

from django.shortcuts import render , HttpResponse

def index(request):
    return HttpResponse('Welcome!')

def create(request):
    return HttpResponse('Create!')

def read(request, id):
    return HttpResponse('Read! '+id)

라우팅 결과 

- 과정예시

1. 127.0.0.1/read/1 접속 

2. django는path('', include('myapp.urls'))로 감 

3. myapp.urls로 위임 

4.path('read/<id>',views.read)로 감

5. views.read로 위임 

6. HttpResponse('Read! '+id)값을 더해서 클라이언트에 보내줌 


Web Server vs. Web Application Server

# Web Server 

- 정적 (static)

- apache, nginxm IIS

- 필요할만한 웹 페이지를 미리 만들어야함 (1.html, 2.html, 3.html)

- 빠르고, 준비할 것이 적음 

 

# Web Appliccation Server

- 동적 (dynamic)

- django, flask, php, jsp, ROL

- 하나만 만들어도 됨 (view.py)

- 느리고, 공부할 것이 많음 

- 유지보수 좋음 (view.py 만 수정하면 됨)

- 개인화된 정보를 생성할 수 있음 


읽기 기능 구현 (READ) 

- topic 딕셔너리로 구성된 topics 리스트 생성

- 각각의 topic 링크 클릭하면 아래에 title과 body가 출력되도록 함 

- HTMLTemplate 함수를 선언하여 공통 html 부분을 구현 

- 파라미터로 article을 받음

- read 험수에서 article에 title과 body값을 작성하여 인자로 넘겨줌 

from django.shortcuts import render, HttpResponse
topics = [
    {'id': 1, 'title': 'routing', 'body': 'routing is..'},
    {'id': 2, 'title': 'view', 'body': 'view is..'},
    {'id': 3, 'title': 'model', 'body': 'model is..'}
]

def HTMLTemplate(articleTag):
    global topics
    str = ''
    for topic in topics:
        str+=f'<li><a href="/read/{topic["id"]}">{topic["title"]}</a></li>'
    return f'''
    <html>
    <body>
        <h1><a href="/">Django</a></h1>
        <ol>
            {str}
        </ol>
            {articleTag}
    </body>
    </html>
    '''

def index(request):
    article='''<h2>Welcome</h2>
        <p>Hello, django</p>'''
    return HttpResponse(HTMLTemplate(article))

def read(request, id):
    global topics
    article =''
    for topic in topics:
        if str(topic["id"]) == id:
            article = f'<h2>{topic["title"]}</h2><p>{topic["body"]}</p>'
    return HttpResponse(HTMLTemplate(article))


쓰기 기능 구현 (CREATE)

- csrf기능 적용하지 않기 :  https://stackoverflow.com/questions/16458166/how-to-disable-djangos-csrf-validation 참고

- csrf_exempt, method_decorator import

- create 기능 구현 후 페이지 redirct 하기 위해 redirect도 import 할 것 

from django.views.decorators.csrf import csrf_exempt 
from django.utils.decorators import method_decorator   
from django.shortcuts import render, HttpResponse, redirect

- create 전과 후를 구분 짓기 위해 if문으로 request.method 가 GET일 때와 POST일 때를 나누어 구현 

-request.method 가 GET : create 링크 클릭 시 title, body를 입력할 수 있는 칸이 생기고 title과 body 입력 후 create 버튼 누르면 post 방식으로 내용이 전달됨 

- request.method 가 POST : 해당 내용을 포함한 새로운 딕셔너리를 생성하고 topics에 append

- 방금 create한 내용을 출력하기 위해 /read/id값 으로 redirect함 

@method_decorator(csrf_exempt, name='dispatch')
def create(request):
    if request.method == "GET":
        article = '''
            <form action="/create/" method="post">
                <p><input type="text" name="title" placeholder="title"></p>
                <p><textarea name="body" placeholder="body" rows=6></textarea></p>
                <p><input type="submit" value="create"></p>
            </form>'''
        return HttpResponse(HTMLTemplate(article))
    elif request.method == "POST":
        title  = request.POST["title"]
        body = request.POST["body"]
        newTopic ={'id':len(topics)+1, 'title':title, 'body':body}
        topics.append(newTopic)
        url = '/read/'+str(newTopic["id"])
        return redirect(url)

결과예시


삭제 기능 구현 (Delete)

<템플릿 수정>

  - 파라미터에 id 값 추가 / 기본값은 None 

  - 기본 화면에서는 id 값이 없으므로 delete 버튼 보이지 않고,

     id 값이 있는 topic 클릭시에만 delete 버튼 보이도록 함 

  -  hidden type의 id값이 post 방식으로 /delete/에 전송됨 

def HTMLTemplate(articleTag, id=None):
    global topics
    contextDelete = ''
    if id!=None:
        contextDelete = f'''<li>
                <form action="/delete/" method="post">
                    <input type="hidden" name="id" value={id}>
                    <input type="submit" value="delete">
                </form>
            </li>'''
    str = ''
    for topic in topics:
        str+=f'<li><a href="/read/{topic["id"]}">{topic["title"]}</a></li>'
    return f'''
    <html>
    <body>
        <h1><a href="/">Django</a></h1>
        <ol>
            {str}
        </ol>
            {articleTag}
        <ul>
            <li><a href="/create">Create</a></li>
            {contextDelete}
        </ul>
    </body>
    </html>
    '''

<delete 함수>

- 빈 배열 newTopics 생성 

- POST방식으로 전달받은 id값과 일치하는 topic을 제외하고 다른 topic들은 빈 배열에 append 

- append 된 배열 newTopics를 topics로 대체 

- 기본 홈 화면으로 redirect

@method_decorator(csrf_exempt, name='dispatch')
def delete(request):
    global topics
    if request.method == 'POST':
        id = request.POST['id']
        newTopics = [] 
        for topic in topics:
            if topic['id'] != int(id):
                newTopics.append(topic)
        topics = newTopics
        return redirect('/')

 

결과예시


수정 기능 구현 (Update)

<템플릿 수정>

- update 링크 추가  

contextStr = ''
    if id!=None:
        contextStr = f'''
            <li>
                <a href="/update/{id}">Update</a>
            </li>
            <li>
                <form action="/delete/" method="post">
                    <input type="hidden" name="id" value={id}>
                    <input type="submit" value="delete">
                </form>
            </li>
        '''

update 함수 구현 

@method_decorator(csrf_exempt, name='dispatch')
def update(request,id):
    global topics
    if request.method == "GET":
        for t in topics:
            if t["id"] == int(id):
                selectedTopic = {'title':t["title"], 'body':t["body"]}
        article = f'''
            <form action="/update/{id}/" method="post">
                <p><input type="text" name="title" value={selectedTopic["title"]}></p>
                <p><textarea name="body" rows=6>{selectedTopic["body"]}</textarea></p>
                <p><input type="submit" value="update"></p>
            </form>'''
        return HttpResponse(HTMLTemplate(article,id))
    elif request.method == "POST":
        title  = request.POST["title"]
        body = request.POST["body"]
        for t in topics:
            if t["id"] == int(id):
                t["title"] = title 
                t["body"] = body
        url = '/read/'+ str(id)
        return redirect(url)

결과예시

 

'STUDY > Python' 카테고리의 다른 글

[ 생활코딩 - Web2 Python ] Flask Framework - CRUD 구현  (0) 2022.12.14
profile

DEVELOP

@JUNGY00N