기본 세팅

 

https://www.django-rest-framework.org/

 

Home - Django REST framework

 

www.django-rest-framework.org

 

# 가상환경에 설치된 목록 확인
pip list
# 설치
pip install django
pip install djangorestframework
pip install django-dotenv
pip freeze > requirements.txt
django-admin startproject drf_week2 .

 

 

 

 

시리얼라이즈

  • 파이썬 객체나 queryset 객체 등을 JSON, XML 형태로 변환하는 것
  • 반대로 JSON 형태를 DB 인스턴스로 변환하는 것은 디시리얼라이즈라고 한다.

JSON 이란?

    Javascript 객체 문법으로 구조화된 데이터를 표현하기 위한 문자 기반의 표준 포맷

     딕셔너리처럼 Key와 Value 값을 가짐

     *parse란? 데이터 해석. deserialization을 포괄 (ex. 압축해제, 코드 컴파일, 브라우저가 html 해석)

 

 

 

 

 (app-models.py)

from django.db import models

class Articles(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField(blank=True, null=True)
    crated_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    #admin 페이지에서 게시글 제목으로 나오게 하기
    def __str__(self):
    	return str(self.title)

 *urls.py, (app)admin.py, (app)urls.py 등의 설정 생략

 

 

(app - views.py)

from rest_framework.response import Response

def articleAPI(response):
    return Response('연결되었습니다.')

 

 

(app - serializers.py 생성)

# field 타이핑 에러 :
#("Creating a ModelSerializer without either the 'fields' attribute or 
#the 'exclude' attribute has been deprecated since 3.3.0, and is now disallowed. 
#Add an explicit fields = '__all__' to the StockSerializer serializer.",)

from articles.models import Articles
from rest_framework import serializers

class ArticleSerialize(serializers.ModelSerializer):
    class Meta:
        model = Articles
        # field 아님. 오타 주의
        fields = '__all__'

 

 

 

 

 

시리얼라이즈 사용X  vs  사용O

from rest_framework.response import Response
from rest_framework.decorators import api_view
from articles.models import Articles
from articles.serializers import ArticleSerialize

#브라우저블 API
@api_view(['GET', 'POST'])
def articleAPI(request):
    articles = Articles.objects.all()
    article = articles[0]
    article_data = {
        'title' : article.title,
        'content' : article.content,
    }
    return Response(article_data)
    

#위와 아래 같은 코드


@api_view(['GET', 'POST'])
def articleAPI(request):
    articles = Articles.objects.all()
    # 여러개의 article을 가져올 때 many =True
    serialize = ArticleSerialize(articles, many=True)
    return Response(serialize.data)

+) 데코레이터 : https://winterakoon.tistory.com/80

 

 

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

[DRF] 03. postman-1, swagger  (0) 2023.04.24
[DRF] 02. @api_view  (0) 2023.04.24
11. Django gitignore, 시크릿 키  (0) 2023.04.24
10. Django 폼  (0) 2023.04.24
[DRF] 00.이론  (0) 2023.04.18

git ignore

 

https://www.toptal.com/developers/gitignore

 

gitignore.io

Create useful .gitignore files for your project

www.toptal.com

 

 

 

위와 같이 입력 후 vs code에서 .gitignore를 생성하여 검색 결과를 붙여넣기

+) gitignore에  venv를 입력하면 git에 push 할 때 가상환경은 무시한다.

 

 

 

 

settings.py

# 추가하기
INSTALLED_APPS = [
    'rest_framework',
]


# 변경하기
LANGUAGE_CODE = 'ko-kr'

TIME_ZONE = 'Asia/Seoul'

 

 

 

 

SECRET_KEY

 

 

.env 파일 생성

SECRET_KEY = 'settings.py에 있던 시크릿키를 가져옴'

settings.py 

import os

SECRET_KEY = os.environ.get('SECRET_KEY')

manage.py

import dotenv

if __name__ == '__main__':
    dotenv.read_dotenv()
    main()

 

+) 에러 : a server error occurred. please contact the administrator

# manage.py 괄호 빠트림
dotenv.read_dotenv

 

 

.gitignore

# 상단에 추가하기
.env

 

 

+) 시크릿 키 재생성

python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'

 재생성된 시크릿키를 .env 파일에 붙여넣기

 

 

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

[DRF] 02. @api_view  (0) 2023.04.24
[DRF] 01. 시리얼라이즈  (0) 2023.04.24
10. Django 폼  (0) 2023.04.24
[DRF] 00.이론  (0) 2023.04.18
09. Django 템플릿 상속  (0) 2023.04.17

Form

  • 페이지 요청시 전달되는 파라미터들을 쉽게 관리하기 위해 사용하는 클래스.
  • 필수 파라미터의 값이 누락되지 않았는지 확인
  • 파라미터의 형식은 적절한지 등을 검증

   

    일반 폼(forms.Form)

    모델 폼(forms.ModelForm) : 연결된 모델의 데이터를 저장. Meta 클래스가 필요.

 

form.py 생성하기

from django import forms
from .models import Product


class ProductForm(forms.ModelForm):
    class Meta:
        # Product 모델과 연결
        model = Product
        fields = ['product_name', 'price', 'desc']

 

views.py

def product_create(request):
    if request.method == 'GET':
        form = ProductForm()
        return render(request, 'mall.html', {'form': form})
    elif request.method == 'POST':
        form = ProductForm(request.POST)
        # 유효성 검사에 실패하면 다시 상품등록 페이지로 이동
        if form.is_valid():
            # 임시저장
            product = form.save(commit=False)
            product.user = request.user
            product.save()
            return redirect('/')

 

 

mall.html

    action 속성을 지정하지 않아도 현재 URL이 디폴트로 설정된다.

{% extends 'base.html' %}
{% block content %}
<div class="container">
    <form method="post">
        {% csrf_token %}
        <!--html 자동생성-->
        {{ form.as_p }}
        <button type="submit" class="btn btn-primary">저장하기</button>
    </form>
</div>
{% endblock %}

 

 

 

 

폼 위젯

 

form.py

from django import forms
from .models import Product


class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = ['product_name', 'price', 'desc']
        widgets = {
            'product_name': forms.TextInput(attrs={'class': '클래스명'}),
            'price': forms.TextInput(attrs={'class': '클래스명'}),
            'desc': forms.Textarea(attrs={'class': '클래스명'}),
        }
        # 다음과 같이 레이블명도 설정할 수 있다.
        labels = {
            'product_name': '상품명',
            'price': '가격',
            'desc': '상품 설명',
        }

 

 

 

 

https://docs.djangoproject.com/en/4.0/topics/forms/

 

 

 

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

[DRF] 01. 시리얼라이즈  (0) 2023.04.24
11. Django gitignore, 시크릿 키  (0) 2023.04.24
[DRF] 00.이론  (0) 2023.04.18
09. Django 템플릿 상속  (0) 2023.04.17
08. Django css  (0) 2023.04.17

1주차

 

 

MVT : urls 파일 -> views.py의 함수 호출 -> 함수 실행 (모델) -> 템플릿

    단점 : 새로고침 됨

DRF : 앞으로 템플릿X. javascript만 사용 장고 rest framework

 

 

1. postman 사용

 

2. cURL 복사 -> (터미널) 붙여넣기 : 웹브라우저 html

 

 

클라이언트        -요청 (request) ->         서버

                         <-응답 (response) -

 

 

프로토콜 : 통신 규약(약속)

ex) HTTP : 하이퍼텍스트 전송 프로토콜(html 전송용으로 탄생)

 

웹 브라우저 흐름

1. 도메인(DNS) 조회

    nslookup 도메인 주소 : ip주소 조회

2.  HTTP 요청 메시지 작성

    postman의 console에 찍힌 것들

3. Socket 라이브러리를 통해 전달

4. TCP/IP 작성되고 이 안에 HTTP 메시지가 포함

 

프로토콜 계층

어플리케이션 => Socket Library => TCP => IP => LAN => 인터넷 

+) 추가: TCP/ IP 란?

 

TCP

IP를 TCP로 보안

    출발지 port 목적지 port 정보

    전송 제어와 순서

    검증 정보 등이 실린다.

 

특징

    연결지향 TCP 3 way handshake를 통해 연결이 되었는지 먼저 확인

    데이터 전달을 보증

    순서를 보장

    신뢰 할 수 있어서 대부분 현재 TCP를 사용

 

 

 

TCP 3 way handshake

1. 클라 -> 서버 : SYN

2. 서버 -> 클라 : SYN + ACK

3. 클라 -> 서버 : ACK

SYN을 통해 연결, ACK를 통해 승인

최적화를 통해 요즘은 3단계에서 데이터를 송신

 

 

 

인터넷 프로토콜 

 

 

    지정한 IP 주소로 전송

    출발지 IP와 목적지 IP를 작성

    송신하면 노드들을 거쳐서 송신됨

 

한계

    받을 대상이 없을 수 있다

    중간에 패킷이 손실되거나 순서대로 오지 않을 수 있다.

    같은 IP를 사용하는 어플리케이션이 여러개라면 문제가 생긴다.

 

 

UDP

    기능이 거의 없다

    TCP 기능들이 없다

    IP와 유사한데 포트와 체크섬만 추가

    어플리케이션에서 추가 작업이 필요

    원하는 기능들을 추가해서 만들 수 있는 프로토콜

 

 

Port

    한 컴퓨터에서 게임 화상통화 웹브라우저를 다 킬 수 있다.

    포트는 같은 IP내에서 프로세스 구분을 해 줄 수 있다.

    0~65535 : 사용할 수 있는 포트

    0~1023 은 사용하지 않는 것이 좋다.

 

URI vs URL vs URN

    URI 는 locator, name 또는 둘 다 추가로 분류 될 수 있다.

    URI 라는 개념 아래에 URL과 URN이 존재

    URN은 거의 쓰지 않는다.

 

 

URI

    Uniform : 리소스 식별을 위한 통일 방식

    Resource : 리소스

    Identifier : 식별자

    포트 생략시 http 80, https 443

    리소스 경로는 계층적 구조로 이루어져있다.

    fragment : 페이지 내에서 위치

 

 

 

HTTP 

    HyperText Transfer Protocol

  • 팀 버너스리가 개발(+ WWW)
  • 원래는 HTML 전송용으로 나왔으나 현재는 모든 형태를 전송

           ex) 이미지, 음성, 영상, 파일, JSON, XML 등

  • 클라이언트 서버 구조
  • stateless

 

역사

 

1. 1991 GET 메소드만 지원, 헤더가 없음

2. 1996  메소드와 헤더 추가

3. 1997 HTTP 1.1

4. 2015 HTTP2 성능 개선

5. 2020 HTTP3

 

 

클라이언트 서버 구조

클라이언트는 Request를 보내고 서버는 Response를 보냄

왜 분리가 중요할까?

    태초에 클라이언트와 서버의 개념이 분리되어 있지 않았다.

    데이터와 비즈니스 로직을 전부 서버(백)에 넣고

    클라이언트(프론트)에는 ui를 다 넣는다

    클라이언트가 모바일, 티비, 웹 모든 것이 될 수 있다.

    서버 또는 트래픽 폭주시 클라이언트는 그대로 두고 서버만 독립적으로 진화시킴

 

 

무상태 프로토콜(stateless)

    서버가 클라이언트 상태를 보존하지 않는다.

    중간에 다른 점원으로 바뀐다고 생각해야 한다.

    무상태는 응답서버를 쉽게 바꿀 수 있다.

    세션 로그인은 상태가 있다. 세션은 최소한으로만 사용

 

 

비연결성 

    요청시마다 연결을 유지하면 클라이언트가 많아지면 서버가 터짐

    연결 유지를 하지 않으면서 최소한의 자원 사용

    HTTP는 기본적으로 연결을 유지하지 않는다

    일반적으로 초단위 이하의 빠른 응답

    1시간 동안 수천명이 써도 실제 동시처리하는 요청은 몇십개도 안된다.

    서버 자원을 효율적으로 쓸 수 있다.

 

 

 

 

HTTP 안좋은 설계 

    각각 url을 만들어서 처리

        ex) 회원 등록, 수정, 삭제등을 각각의 url로 만듬

    리소스  식별

 

 

리소스란?

    회원이라는 개념이 리소스.

    이것이 URI에 매핑됨

    거기에 하는 행위는 메소드로 하는 것

        ex) /user/{id} 회원의 등록, 수정, 삭제를 처리

    

리소스와 행위를 분리하는 것이 Restful API

    리소스 : 회원

    행위 : 조회, 등록, 삭제, 변경

 

 

메소드

    Get : 조회

  • 데이터는 쿼리 스트링으로 전달

      주소창에 =, ? 등으로 전달되는 정보

 

    Post : 등록(DB)

  • 메시지 바디를 통해 서버로 요청 데이터 전달
  • 데이터를 처리
  • 혹은 프로세스를 처리. (배달 시작 버튼처럼 데이터가 없어도 프로세스 상태가 변경되는 경우) POST  /order/{orderId}/start-delivery
  • 새로운 리소스가 생성되지 않을 수도 있음
  • JSON으로 조회 데이터를 넘기고 싶은데 GET 메서드 쓰기 힘든 경우에도 씀
  • GET은 캐싱 할 수 있어서 가능한 경우 GET을 쓴다.

    Put : 대체, 혹은 생성

  • 파일 붙여넣기와 동일, 없으면 만들고 있으면 덮어씀
  • 포스트와 차이점은 put은 클라이언트가 URI를 지정해서 보냄
  • 내용을 전체 다 가지고 옴

 

    Patch : 내용의 일부분 변경

    Head : Get과 동일하지만 상태줄과 헤더만 반환

 

메소드의 속성

    안전: 리소스가 변경이 되냐 안되냐

    멱등 : 몇번 하든 결과가 같다. GET/PUT/DELETE는 결과가 같다. POST는 중복돼서 발생할 수 없어짐. 멱등 여부에 따라 timeout시에 재요청 해도 되냐가 결정

    캐시기능 : GET, HEAD 정도만 캐시

 

데이터 전송

    쿼리 파라미터

        GET, 주로 검색, 정렬 필터

    메시지 바디

        POST, PUT, PATCH, 회원가입, 상품주문, 리소스 등록 변경

 

HTML Form을 통한 데이터 전송

    회원가입, 주문, 데이터 변경

    HTML Form 은 Get, Post만 지원

    Content-Type : application/ x- www-form-urlencoded

        username-kwon&age=20 식으로 바디 데이터 쿼리 파라미터처럼 실림

        전송 데이터는 url encoding 처리 된다.

    Content-Type : multipart/form-data

         파일을 같이 보낼 때 써야 함. 바이너리 데이터 보낼 때 사용

         다른 종류의 여러 파일과 폼의 내용을 함께 전송 가능

 

HTTP API를 통한 데이터 전송

    회원가입, 주문, 데이터 변경

    서버 to 서버, 앱 클라이언트, 웹 클라이언트(ajax)

    Content-Type: application/json

    Form 대신 JS를 이용한 통신

    Post, Put, Patch도 메시지 바디로 데이터 전송 가능

 

 

API 설계 예시

    GET/ user : 회원 목록

    POST/user : 회원 등록

    GET/ user/{id} : 회원 조회

    PATCH, PUT, POST/user/{id} : 회원 수정

    DELETE/ user/ {id} : 회원 삭제

 

클라이언트는 동록될 리소스의 URI를 모른다.

서버가 리소스의 URI를 생성한다

/user 가 컬렉션 된다.

 

 

 

HTTP 상태 코드

1xx : 요청이 수신되어 처리중. 거의 사용x

2xx : 

    200 OK

    201 Created

        : Header에 Location을 추가해서 새로운 리소스의 URI를 알려줄 수 있다.

    202 Accepted

        : 요청은 접수했다

    204 No Content

        : save 버튼을 눌러 저장만 하고 화면 변화가 필요 없을 때

3xx: 추가 행동 필요

    웹브라우저는 3xx의 헤더에 Location이 있으면 자동으로 리다이렉트 한다.

    영구 리다이렉트 : 영구 이동, 메소드와 바디가 바뀌는 301 안바뀌는 308이 있다.

    일시 리다이렉트 : 일시적 변경. 주문완료 후 주문 내역으로 이동

        302 : 리다이렉트시 메소드틑 GET. 본문은 제거

        307 : 리다이렉트시 메소드와 본문 유지

        PRG(Post/Redirect/Get)

            Post 주문 후 새로고침시 중복주문이 가능하다.

            주문 완료시 302를 줘서 리다이렉트 시키면 새로고침해도 결과 화면만 다시 요청한다.

4xx : 클라이언트 에러

    잘못된 문법. 오류의 원인이 클라이언트

        400 : 요청 내용을 다시 검토. API 스펙이 맞는지를 확실히 해야 한다. (프론트)

        401 : 인증이 안됨

        인증 vs 권한 : 인증은 로그인이 안됐다. 권한은 내가 운영자가 아니다. Authentication vs Authorization

        오류는 Unauthorized로 그냥 쓰고 있다.

        403 : 권한이 없다. 로그인된 회원이 운영진이 아니다.

        404 : 리소스가 없다. 숨기고 있다. (개발시 주로 url 틀렸을 때)

5xx : 서버 에러

    복구 후 재시도시 성공 가능하다.

        500 : 서버 내부 문제

        503 : 서버 일시 과부하

 

 

 

HTTP Header

    field-name(key)는 대소문자 구분이 없다.

        content-type(필드값) = Content-Type

    HTTP 전송에 필요한 모든 부가정보

        메시지 바디의 내용

        메시지 바디의 크기

        압축

        인증

        요청 클라이언트

        캐시 관리

    표준 헤더가 너무 많고 필요시 임의의 헤더도 추가 가능

        HTTP headers - HTTP | MDN(mozila.org)

    헤더에는 바디의 데이터를 해석할 수 있는 정보를 제공

 

 

표현에 관한 헤더

    리소스가 html vs xml vs json ? 중에 뭘로 표현했는가

        Content-Type: 형식

            text/html;charset=utf-8

            aplication/json

            image/png

        Content-Encoding : 압축방식, 압축해서 보내준 경우

            gzip

            deflate

            identity : 압축 안 함

        Content-Language

            ko

            en

            en-US

        Content-Length : 길이

            바이트 단위

            Transfer-Encoding 사용시 Content Length는 사용하면 안 됨

 

 

컨텐트 협상(Content Negotiation)

    협상 헤더는 요청시에만 사용

        Accept : 클라이언트가 선호하는 미디어 타입 전달

            구체적인것이 우선된다.

            text/plain;format=flowed

            text/plain

            text/*

        Accept-Charset : 클라이언트가 선호하는 문자 인코딩

        Accept-Encoding : 클라이언트가 선호하는 압축 인코딩

        Accept-Language : 클라이언트가 선호하는 자연 언어

            서버에서 다중 언어를 지원

            한국어 브라우저를 쓰면 한국어를 선호한다는 것을 알려준다

            서버에서 한국어로 보내준다.

            여러가지 언어에 대한 우선순위가 필요한 경우 quality values(q)를 사용한다.

            1이 가장 높고 0이 가장 낮다. 생략시 1

            accept-language: en;q=0.9 ko;q=0.8

 

 

 

전송 방식 헤더

    단순 전송

        Content-Length

    압축 전송

        gzip같은 걸로 서버에서 압축시 절반 정도로 줄어든다.

        Content-Encoding : gzip으로 알려줘야 클라이언트에서 알고 푼다.

    분할 전송

        Transfer-Encoding : chunked

            content length를 보내면 안된다.

        용량이 클 걸 분할해서 전송한다.

    범위 전송

        Range 명시로 어디서 어디까지 왔는지

 

 

일반 정보

    referer : 어디에서 왔냐. 유입 경로 분석용

    user-agent ; 어느 브라우저냐? 특정 브라우저에서만 오류가 생기는 것을 파악하기 좋다. 사용자들이 어느 브라우저를 사용하는지 알 수 있다.

    server : 요청을 처리하는 서버의 소프트웨어 정보

 

특별 정보

    Host : 요청한 호스트 정보(도메인) 필수값

        하나의 서버에 여러 IP가 있을 수 있기 때문에 필요하다. 초창기에 많은 문제가 있었다.

        그래서 Host는 필수로 들어가게 됐다.

    Allow : 허용 가능한 메서드. 405 리스폰스를 줄 때 응답에 포함한다.

    Retry-After : 날짜 혹은 초단위 표기로 다시 요청을 하라고 하나 사용하기는 쉽지 않다.

 

 

인증

    Authorization : 클라이언트의 인증정보를 서버에 전달.

        인증 방식에 따라 들어가는 값이 상이하다.

    WWW-Authenticate : 리소스 접근시 필요한 인증 방법 정의

        리스폰스 시 401 Unauthorized와 함께 사용. 어떻게 인증정보를 만들지에 대한 정보

 

 

쿠키

HTTP는 무상태 연결이기에 상태를 매번 보내줘야 한다.

모든 요청과 링크에 사용자 정보를 포함해야 한다는 단점이 있다.

이를 해결하기 위해 쿠키가 도입됐다.

 

    Set-Cookie : 리스폰스시 서버에서 클라이언트로 쿠키 전달

        만료기간/경로/도메인을 설정

        사용처 : 로그인 세션 관리(쿠키-세션 방식), 광고 정보 트래킹

        쿠키는 항상 서버에 전송되다 보니 트래픽이 추가 유발된다. 최소한의 정보만 쓰자.

        서버에 전송이 필요 없고, 웹 브라우저에 저장하고 싶으면  localStorage를 쓰면 된다.

        보안에 민감한 주민번호, 신용카드 번호 등은 저장하지 않는다.

        만료일자를 생략하면 브라우저 종료시 삭제

        만료일(expires)나 시간(max age)를 지정할 수 있다.

        경로 지정으로 원하는 도메인만 쿠키를 보낸다.

    Cookie : 클라이언트가 서버에서 받은 쿠키 저장. 요청시 서버로 전달.

 

 

HTTP Header(2) - Cache

    캐시가 없다면 매번 같은 요청이 와도 헤더와 바디를 새로 보내준다.

    네트워크는 느리고 비싸므로 아껴 써야 한다.

    브라우저 캐시가 있다면

    cache-control 을 통해서 리스폰스가 캐시의 유효 기간을 설정해 준다.

    응답 결과를 브라우저에 저장해두면 두번째 요청을 캐시에서 받아온다.

    캐시 유효 기간이 지났다면 다시 서버를 통해 데이터를 조회하고 다운로드한다.

 

검증 헤더와 조건부 요청

    캐시 유효기간 초과한 경우 둘 중 하나의 상황

        1.서버에서 기존 데이터가 변경됨

        2. 기존 데이터가 동일함

    검증 헤더 Last-modified를 추가해서 데이터에 변경이 있었는지 없었는지 정보를 추가한다.

    검증 헤더를 보고 캐시의 유효기간만 늘려줄 수 있다.

    if - modified-since를 이용해서 다시 보내줘야하는지 판단 할 수 있다. 304를 이용해서 캐시 데이터를 쓴다.

 

캐시와 조건부 요청 헤더

    Cache-control : max-age

        캐시 유효기간

    Cache-control : no-cache

        서버에 검증하고 사용

    Cache-control : no-store

        민감한 정보로 최대한 빨리 삭제

 

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

11. Django gitignore, 시크릿 키  (0) 2023.04.24
10. Django 폼  (0) 2023.04.24
09. Django 템플릿 상속  (0) 2023.04.17
08. Django css  (0) 2023.04.17
07. Django from 태그  (0) 2023.04.16

태그와 엘리먼트
    태그 : <table>

    엘리먼트 : <table> ~ </table> 처럼 table 태그로 시작해서 table 태그로 닫힌 구간(Block)

 

 

 

템플릿 상속

 


base.html

{% load static %}
<!doctype html>
<html lang="ko">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" type="text/css" href="{% static 'bootstrap.min.css' %}">
    <title>Hello!</title>
</head>
<body>
<!--여기에 템플릿이 삽입-->
{% block content %}
{% endblock %}
</body>
</html>

{% block content %} {% endblock %}  :  base.html을 상속한 템플릿에서 개별적으로 구현해야 하는 영역

 

 

 

 

mall.html

{% extends 'base.html' %} 
{% block content %} 
<div class="container my-3"> 
	<table class="table"> 
    
    	<!--mall 본문 내용-->
        
    </table>
</div> 
{% endblock %}

 

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

10. Django 폼  (0) 2023.04.24
[DRF] 00.이론  (0) 2023.04.18
08. Django css  (0) 2023.04.17
07. Django from 태그  (0) 2023.04.16
06. Django URL 별칭  (0) 2023.04.10

1. static 디렉터리

(setting.py)

STATIC_URL = 'static/' STATICFILES_DIRS = [ BASE_DIR / 'static', ]



(static - style.css)

input[type=submit] {
    margin-top:10px;
}

 


(mall.html)

<!--최상단에 삽입-->
{% load static %} 
<link rel="stylesheet" type="text/css" href="{% static 'style.css' %}">

 

 

 

 

 

 

 

 

2. 부트스트랩

 

다운로드
https://getbootstrap.com/docs/5.1/getting-started/download/

    bootstrap.min.css 파일을 카피하여 스태틱 디렉터리에 저장

 

부트스트랩 클래스
https://getbootstrap.com/docs/5.1/getting-started/introduction/

 

 

(mall.html)

<!--최상단에 삽입-->
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'bootstrap.min.css' %}">






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

[DRF] 00.이론  (0) 2023.04.18
09. Django 템플릿 상속  (0) 2023.04.17
07. Django from 태그  (0) 2023.04.16
06. Django URL 별칭  (0) 2023.04.10
05. Django 템플릿  (0) 2023.04.10

*앞의 문서들과 이어지지 않을 수 있습니다.*

 

form 태그

  • form 태그 안의 버튼은 form의 데이터를 전송하는 역할을 한다.
  • submit이 눌렸을 때 서버로 보내고 싶은 path는 form 태그의 action으로 담는다.
  • 데이터를 서버로 보낼때 method='post'를 입력한다.
  • {% csrf_token %} : 데이터가 실제 웹페이지에서 작성했는지 판단하는 보안. Post 요청시 form 바로 밑에 없으면 오류를 낸다.
  <form class="form-area" action="{ url 'product_detail' shop.id}" method="post">
    <!--보안-->
    <!--버튼을 누르면 sign-in으로 post요청을 보냄-->
    {% csrf_token %}
    <div class="form-group mt-2 mb-2">
      <label for="product">상품명</label>
      <input type="text" class="form-control" id="productquestion" name="productquestion">
    </div>
    <hr>
    <div style="float: right">
      <button type="submit" class="btn btn-primary">등록</button>
    </div>

 

 

views.py

from django.shortcuts import render, redirect, get_object_or_404
from .models import Product


def product_answer(request, id):
    product_item = get_object_or_404(UserModel, pk=id)
    product_item.product_set.create(content=request.POST.get('content')
    return redirect('product_detail', id:id)

Product과 UserModel 모델이 ForeignKey 로 연결되어 있기때문에 참조 혹은 역참조로 사용할 수 있다.

 

 

 

mall.html

<h1>{{ product.description }}</h1>
<h5>{{ product_item.product_set.count }}개의 상품이 있습니다.</h5>

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

09. Django 템플릿 상속  (0) 2023.04.17
08. Django css  (0) 2023.04.17
06. Django URL 별칭  (0) 2023.04.10
05. Django 템플릿  (0) 2023.04.10
04.5 Django 관리자  (0) 2023.04.09

URL 별칭

  • url 매핑에서 name 속성을 사용한다.
  • url 하드코딩을 할 경우 링크 구조가 변경된다면 템플릿에서 url을 하나씩 수정해야한다.
  • html 파일 뿐 아니라 redirect에서도 사용할 수 있다.

 

(urls.py)

from django.urls import path
from . import views

urlpatterns = [
    path('<int:product_id>/', views.product_detail, name='product_detail'),
]

 

(templates-product-mall.html)

<!--URL 별칭-->
<!--shop.id는 url의 product_id에 전달되는 값-->
<a class="nav-link" style="text-align:right" href="{% url 'product_detail' shop.id  %}">
	주문하기<span class="sr-only"></span>
</a>


<!--URL 하드코딩-->
<a class="nav-link" style="text-align:right" href="/{{shop.id}}">
	주문하기<span class="sr-only"></span>
</a>

 

 

 

 

 

URL 네임스페이스

    url 별칭을 사용할 경우 타앱과 url 별칭 중복이 발생할 수 있다.

 

(urls.py)

from django.urls import path
from . import views

app_name = 'order'

urlpatterns = [
    path('<int:product_id>/', views.product_detail, name='product_detail'),
]

 

(mall.html)

<!--app_name order의 url 별칭이 product_detail-->
<!--다음과 같이 파라미터 명을 정의할 수 있다-->
<!--공백을 사용하여 여러개의 파라미터를 사용할 수 있다-->
{% url 'order:product_detail' product_id = shop.id page=2%}

 

 

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

08. Django css  (0) 2023.04.17
07. Django from 태그  (0) 2023.04.16
05. Django 템플릿  (0) 2023.04.10
04.5 Django 관리자  (0) 2023.04.09
04.Django 모델  (0) 2023.04.09

정렬하기

    order_by( )는 정렬하는 함수이다. create_date에 - 기호가 붙어 있으면 역방향, 없으면 순방향 정렬

from django.shortcuts import render, redirect
from .models import Product

def show_list(request):
	product_list = Product.objects.order_by('-create_date')
    return redirect('/')

 

 

 

 


템플릿 설정하기

    (settings.py - TEMPLATES에 추가하기)

#app에서 공동으로 사용할 templates 폴더 생성
'DIRS': [BASE_DIR / 'templates'],

 

 

 

 

 

템플릿 태그

 

    1. 분기

{% if 조건문 %}
{% elif 조건문 %}
{% else %}
{% endif %}

 

  2. 반복

{% for i in item %}
'''
여기서 forloop 사용 가능
forloop.counter	    루프내의 순서로 1부터 표시
forloop.counter0    루프내의 순서로 0부터 표시
forloop.first	    루프의 첫번째 순서인 경우 True
forloop.last	    루프의 마지막 순서인 경우 True
'''
{% endfor %}

 

    3. 객체 출력 

{% item.id %}

 

    *템플릿 문법 참조 : https://docs.djangoproject.com/en/4.0/topics/templates/

 

 

 

 

 


디테일 페이지

 

(urls.py)

  • 로컬 ip/5 : product_id에 5가 저장된 후 product_detail 함수가 실행된다.
  • views.py에서 question_id를 사용하지 않더라도 인자로 product_id를 받아줘야 한다.
from django.urls import path
from . import views

urlpatterns = [
    path('<int:product_id>/', views.product_detail, name='product_detail'),
]

 

(views.py)

def product_detail(request, id):
	#(DB)id = id(POST에서 불러온 값)
	product = Product.objects.get(id=id)
    
	# user의 signup.html을 화면에 보여주는 함수
	# templates / product / mall.html
	return render(request, 'product/mall.html', {'product':product})

 

(mall.html)

<h1>{{ product.description }}</h1>

 

 

 

 

 

 

오류 페이지

    DoesNotExist(500) : 로컬 ip / product_id 값이 없을 때 발생하는 오류를 404 페이지로 리턴하고자 한다.

from django.shortcuts import render, get_object_or_404
from .models import Product


def product_detail(request, id):
    # pk = Primary Key(기본키)
    product = get_object_or_404(Product, pk=product_id)
    return render(request, 'product/mall.html', {'product':product})

 

 

 

 

 


Primary Key 와 Unique Key 차이

    Primary Key : 주민등록번호, 전화번호 같은 데이터를 식별하고자 할 때 사용하는 키. 테이블당 하나의 pk만 지정할 수 있으며, NULL 값을 허용하지 않는다.

    Unique Key : 아이디 중복 검사 등 유일성을 부여할 때 사용하는 키. NULL 값을 허용한다.

 

 

*제네릭뷰(Generic View) : 비슷한 패턴의 내용을 간략하게 만든 것.

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

07. Django from 태그  (0) 2023.04.16
06. Django URL 별칭  (0) 2023.04.10
04.5 Django 관리자  (0) 2023.04.09
04.Django 모델  (0) 2023.04.09
03. Django URL  (0) 2023.04.07

관리자 계정 생성하기

 

python manage.py createsuperuser

 

 

 

모델 관리하기

    로컬 ip/admin으로 접속하면 모델이 추가된 것을 확인할 수 있다.

from django.contrib import admin
from .models import Product(모델명)

# admin 사이트에 Product 테이블 생성
admin.site.register(Product)

 

 

 

모델 검색

    아래와 같이 수정하면 관리자 페이지에 검색기능을 추가할 수 있다.

from django.contrib import admin
from .models import Product


class ProductAdmin(admin.ModelAdmin):
    search_fields = ['description']


admin.site.register(Product, ProductAdmin)

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

06. Django URL 별칭  (0) 2023.04.10
05. Django 템플릿  (0) 2023.04.10
04.Django 모델  (0) 2023.04.09
03. Django URL  (0) 2023.04.07
02. Django 프로젝트와 앱  (0) 2023.04.05

+ Recent posts