django

django restful

Posted by 동식이 블로그 on February 7, 2019

CRUD를 restful하게 바꿔보기 + image 업로드

crud = function based view || class based view

Restful

new / create 묶기

edit / update 묶기

1
2
3
4
5
6
7
8
9
10
11
# photo urls.py
from django.urls import path
from . import views

app_name= "photos"

urlpatterns = [
    path("", views.list, name="list"),
    # / 오류 적게?
    ## class based view에서 list를 사용
]
1
2
3
4
5
# photo views.py
from django.shortcuts import render

def list(request):
    return render(request, "photo/list.html")
1
# base.html 생성 후 list.html 생성
1
2
3
4
5
6
7
8
9
# base.html

	<!--예전에 쓰던 url 코드-->
<li><a href="/photos/list/">Home</a></li>

	<!--앞으로 바꿀 url 코드-->
	<!--변수처럼 사용! -->
<li><a href="{% url 'photos:list '%}">Home</a></li>
<li><a href="{% url 'photos:create' %}">Create</a></li>

글작성(create)

1
2
3
4
5
# photo urls.py

# new를 만들지 않는다~
# 하나로 통합! --> restful하다
path("create/", views.create, name="create"),
1
2
3
4
5
6
7
8
# models.py
from django.db import models

class Photo(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)    
1
2
3
$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py createsuperuser
1
2
3
4
5
# photo admin.py
from django.contrib import admin
from .models import Photo

admin.site.register(Photo)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# photo views.py
## 지금껏 create / new라는 두개의 url로 create를 구현
### get방식 create 1개랑
### post방식 create 1개를 나누어서 분리 구현
def create(request):
    if(request.method == "POST"):
        # POST방식으로 들어왔을 때
        # 데이터를 저장
        
        pass
    else:
        # GET방식으로 들어왔을 때
        # 입력할 수 있게 폼을 제공
        return render(request, "photo/create.html")

get방식

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# create.html
{% extends "photo/base.html" %}

{% block bb %}
	# action을 없애고 메소드만 POST로
    ## action을 지정해 주지 않아도 photos/create/로 ...
    ## 기본적을 지정해 주지 않았을 때 현재의 url로 방식만 POST로 바꿔서 		   그대로 보내주게 됨
    <form method="POST">
        {% raw %}{% csrf_token %}
        <input type="text" name="title"/>
        <input type="text" name="content"/>
        <input type="submit" value="Submit"/>
    </form>

{% endblock %}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# photo views.py
## 지금껏 create / new라는 두개의 url로 create를 구현
### get방식 create 1개랑
### post방식 create 1개를 나누어서 분리 구현
def create(request):
    if(request.method == "POST"):
        # POST방식으로 들어왔을 때
        # 데이터를 저장
        title = request.POST.get("title")
        content = request.POST.get("content")
        
        Photo.objects.create(title=title, content=content)
        
        return redirect("photos:list")
    else:
        # GET방식으로 들어왔을 때
        # 입력할 수 있게 폼을 제공
        return render(request, "photo/create.html")

리스트페이지에 보여주기
1
2
3
4
# views.py
def list(request):
    photos = Photo.objects.all()
    return render(request, "photo/list.html", {"photos":photos})
1
2
3
4
5
6
7
8
9
10
11
# list.html
{% extends "photo/base.html" %}

{% block bb %}

    <h1>여기는 리스트 페이지</h1>
    
    {% for photo in photos %}
    <h3>{{photo.title}}</h3>
    {% raw %}{% endfor %}
{% endblock%}

읽기(read) - detail

1
2
# photo urls.py
path("<int:id>/", views.detail, name="detail")
1
2
3
4
5
# photo views.py
def detail(request, id):
    photo = Photo.objects.get(id=id)
    
    return render("photos/detail.html", {"photo":photo})
1
2
3
4
5
6
7
8
9
10
11
# detail.html
{% extends "photo/base.html" %}

{% block bb %}

    <h2></h2>
    <h3></h3>
    <h4></h4>
    <h4></h4>

{% endblock%}

update

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# photo views.py
def update(request,id):
    if(request.method == "POST"):
        photo = Photo.objects.get(pk=id)
    
        title = request.POST.get("title")
        content = request.POST.get("content")
        
        photo.title = title
        photo.content = content
        photo.save()
        
        return redirect("photos:detail", photo.id)
    
    else:
        photo = Photo.objects.get(pk=id)
        return render(request, "photo/update.html", {"photo":photo} )
    
1
2
3
4
5
6
7
8
9
10
11
12
13
# update.html
{% extends "photo/base.html" %}

{% block bb %}

    <form method="POST">
        {% csrf_token %}
        <input type="text" name="title" value=""/>
        <input type="text" name="content" value=""/>
        <input type="submit" value="Submit"/>
    </form>

{% endblock %}

delete

1
2
# photo urls.py
path("<int:id>/delete/", views.delete, name="delete"),
1
2
3
4
5
6
# photo views.py
def delete(request, id):
    photo = Photo.objects.get(pk=id)
    photo.delete()
    
    return redirect("photos:list")
1
2
# detail.html
<a href="{% url 'photos:delete' photo.id %}">삭제</a> 

정적파일 static

  • static 폴더안에 base.css생성

  • static 폴더안에 css , img, js, 폴더로 따로따로 만들어서 정리
  • setting.py 안에 121 line STATIC_URL = 에 따로 경로
1
2
3
4
# static base.css
h1 {
    color:red;
}
1
2
3
4
5
6
# photo base.html
<!-- 맨 위에 -->
{% load static %}

<!-- head부분에 추가 -->
<link rel="stylesheet" href="{% static 'base.css' %}" type="text/css" />
1
2
<!-- 파비콘 넣기 -->
<link rel="shortcut icon" href="{% static 'img/a.jpg' %}">

404 page

사용자가 입력한 이미지 column 추가

폼 구성
1
2
3
4
5
# models.py
from imagekit.models import ProcessedImageField
from imagekit.processors import ResizeToFill, ResizeToFit

image = models.ImageField(blank=True)
1
2
3
4
# 외부라이브러리 추가 (ImageField를 사용하기 위해)
$ pip install Pillow
$ pip install pilkit
$ pip install django-imagekit
1
2
$ python manage.py makemigrations
$ python manage.py migrate
1
2
3
4
5
# photo create.html에 추가
## 파일 업로드시 form에 enctype 추가
<form method="POST" enctype="multipart/form-data">
## 이미지 형식 아니면 안받겠다
<input type="file" name="image" accept="image/*"/>
저장
1
2
3
# photo views.py
## create에 추가
image = request.FILES.get("image")
1
2
# detail.html 추가
<img src="" alt=""></img>
1
2
3
4
5
# setting.py
## 이미지 업로드된 장소를 지정해주기 위해
### 맨 밑에
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
1
2
3
4
5
6
7
# mysite urls.py
# django static 파일을 넣으려면 추가
from django.conf.urls.static import static
from django.conf import settings

## 위에 urlpatterns에 추가 
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

이미지 리사이징

  • 원본 / 서비스 / 섬네일 3가지 사이즈로

  • 이미지 리사이징을 위한 라이브러리 설치

1
2
$ pip install pilkit
$ pip install django-imagekit
1
2
3
# setting.py
INSTALLED_APPS에 추가
'imagekit',
1
2
3
4
5
6
7
8
9
10
11
# models.py
from imagekit.models import ProcessedImageField
from imagekit.processors import ResizeToFill, ResizeToFit

# 기존 image를 주석
image = ProcessedImageField(
    upload_to = "photo/image",
    processors = [ResizeToFill(150, 150)],
    format = 'JPEG',
    options = {"quality":90}
)

makemigrations / migrate

  • 필드가 바뀔때는 다시해야하지만 안의 함수를 수정할 때는 상관 없음

댓글달기