Django Rest Framework와 React에서 이를 이용해 Shopping mall 만들기

https://www.youtube.com/watch?v=JD-age0BPVo&list=PLzMcBGfZo4-kCLWnGmK0jUBmGLaJxvi4j&index=2 

위 유튜브 Django & React Tutorial #1 ~ #3을 참고하였다.

 

 

기본 흐름은 다음과 같다.

 

 

 

 

DRF 세팅

 

1. 프로젝트 폴더 만들기 및 visual studio code로 해당 폴더 열기

 

 

2. 확장 프로그램 설치(장고, 코드에디터, 아래 snippets들)

 

 

3. django 프로젝트 폴더 생성

django-admin startproject shop_controller

- 이렇게 하면 shop_controller 폴더가 생성되고, 그 안에 설정파일을 모아 놓은  shop_controller 폴더가 또 생성됨.

 shop_controller/shop_controller 는 프로젝트의 설정 담당하는 것들이라고 보면 됨.

 

 

4. 프로젝트 폴더 안에 api로 사용할 app 만들기 (이름 api로 했음)

cd shop_controller 
django-admin startapp api

 

 

5. api 앱의 apps.ApiConfig, rest_framework shop_controller/settings.py에 추가해주기

INSTALLED_APPS = [
...
    'api.apps.ApiConfig',
    'rest_framework',
]

 

 

6. api 앱에 urls.py 생성 (앱별 url 관리하고, 나중에 통합 urls.py(프로젝트 폴더의 urls)에서 관리하기 위해)

# api.urls.py

from django.urls import path
from .views import main

urlpatterns = [
    path('', main),
]

 

 

7. shop_controller/urls.py에 위 urls including. 'api/' 경로로 온 것은 다 api.urls로 보내는 것. 그리고 위 api.urls에서 처리해서 page 보여주는 것

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

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

 

 

8. 테스트용 view 작성

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.


def main(request):
    return HttpResponse("Hello")

 

 

9. migrate하여 db 변경사항 저장

python manage.py migrate

 

 

10. model에 Item class 작성 후 migrate

from django.db import models

# Create your models here.
class Item(models.Model):
    writer = models.CharField(max_length=50, unique=True)
    image = models.ImageField(verbose_name='image', null=True, blank=True)
    listing_or_not = models.BooleanField(null=False, default=False)
    like_count = models.IntegerField(null=False, default=0)
    created_at = models.DateTimeField(auto_now_add=True)

 

 

11. serializers.py 생성 >> 위 모델에서 Item 클래스(필드)를 json으로 변환하여 응답해주기 위한 기능

from rest_framework import serializers
from .models import Item

class ItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = Item
        fields = ('id', 'writer', 'image',
                'listing_or_not', 'like_count', 'created_at')

 

 

12. views.py 변경. 위에서 만든 models와 serializers 적용한 json 값 보여주도록. 우선 CreateAPIView로 보여주기.(글 작성 및 확인 가능한 View)

from django.shortcuts import render
from rest_framework import generics
from .models import Item
from .serializers import ItemSerializer

class ItemView(generics.CreateAPIView):
    queryset = Item.objects.all()
    serializer_class = ItemSerializer

 

 

13. api/urls.py 에 새로 만든 view class 추가

from django.urls import path
from .views import ItemView

urlpatterns = [
    path('', ItemView.as_view()),
]

 

 

 

 

리액트(React) 세팅

 

1. 프로젝트 폴더에 frontend app 만들고, 해당 앱 안에 static(+ /images, css, frontend(js 번들 저장할 곳)), templates 폴더 추가

django-admin startapp frontend

 

현재까지 디렉토리 구성

 

 

2. packge.json 만들기 ( frontend 프로젝트를 위해 다운, 사용한 node module, packg json 등 기록되는 것)

npm init -y

 

 

3. webpack 및 babel 설치

* webpack : js 파일을 하나로 합쳐주는 것. 여러개 파일로 로딩하는 것은 네트워크 비용이 많이 들고, 또 변수 충돌의 위험이 있음.

* babel : 브라우저가 최신 js 코드를 인식 못하는 경우가 있을 수 있음. babel js를 compile 해주어 해당 에러 방지할 수 있음

npm i webpack webpack-cli --save-dev
npm i @babel/core babel-loader @babel/preset-env @babel/preset-react --save-dev

 >> --save-dev로 저장하면, package.json에 그냥 dependencies가 아닌, devDependencies에 저장된다. 개발환경과 분리해주는 것.

 

 

4. react-dom 설치

UI를 브라우저에 렌더링 할때 사용하는 라이브러리.

근데 react(18 이상)부터는 지원하지 않고, ReactDOM.createRoot() API가 대체한다고 한다. 바꿀 필요가 있어보임.

npm i react react-dom --save-dev

 

 

5. Material-UI 설치. 웹 디자인 css 작성을 위한 프레임워크. 부트스트랩 같은 역할. icons는 1000여개 이상의 아이콘 제공해줌.

* 혹시 다운이 안되면 --save ... 붙여서 실행하면 됨

npm install @material-ui/core --save --legacy-peer-deps
npm install @material-ui/icons --save --legacy-peer-deps

 

 

6. plugin-proposal-class-properties >> class 내에서 instance 변수 선언 및 arrow function을 멤버 메소드로 사용할 수 있게 해줌.

npm install @babel/plugin-proposal-class-properties

 

 

7. react-router-dom 설치. react에는 router(url 처리하여 페이지 보여주는 것.)가 기능 내장된게 없어서 library 써야 한다 함.

>npm install react-router-dom

 

 

8. frontend 앱에 babel.config.json 생성.

- 설치한 라이브러리들을 presets 및 plugins으로 사용

- node에 현재 사용중인 node js 버젼 넣으면 됨

{
    "presets": [
        [
            "@babel/preset-env",
            {
            "targets": {
                "node": "16"
            }
            }
        ],
        "@babel/preset-react"
    ],
    "plugins": ["@babel/plugin-proposal-class-properties"]
}

 

 

9. webpack.config.js 생성

- 우리의 entry js 파일 있는 위치, output할 위치 등 설정.

- lodaer로 babel-loader 사용한다는 의미,

- optimization에서 minimize하여 공백 다 없애서 로딩시간 줄이기.

const path = require("path");
const webpack = require("webpack");

module.exports = {
    entry: "./src/index.js",
    output: {
    path: path.resolve(__dirname, "./static/frontend"),
    filename: "[name].js",
    },
    module: {
    rules: [
        {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
            loader: "babel-loader",
        },
        },
    ],
    },
    optimization: {
    minimize: true,
    },
    plugins: [
    new webpack.DefinePlugin({
        "process.env": {
        // This has effect on the react lib size
        NODE_ENV: JSON.stringify("production"),
        },
    }),
    ],
};

 

 

10. package.json scripts 부분 수정

- dev일 때는 webpack을 development, watch 모드로 실행.

 >> js 파일이 변경되거나 하면 서버 재시작해서 변경사항 적용 확인되도록

- build일 때는 production 모드로 실행

"scripts": {
    "dev" : "webpack watch --mode development",
    "build" : "webpack --mode production"
  },

 

 

11. frontend urls 추가 및 settings.py urls에에 해당 url 추가

# frontend/urls

from django.urls import path
from .views import index

urlpatterns = [
    path('', index),
]


# settings/urls

...

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

 

 

12. index.html, index.js, App.js 작성

index.js 가 Entry file이고 이게 App.js를 importing 해서,

App.js에서 rendering될 부분에 rendering할 내용 날려주고(여기선 index.html에 App 클래스 날려줌)

index.html은 해당 페이지를 보여주는 것.

// index.js

import App from './components/App';


// App.js

import React, { Component } from "react";
import { render } from "react-dom";

// 현재 파일의 default 앱
export default class App extends Component {
    constructor(props){
        super(props);
    }

    render(){
        return (<h1>Testing React Code</h1>);
    }
}

const appDiv = document.getElementById("app");
render(<App />, appDiv);


// index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Item Controller</title>
        {% load static %}
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <link
            rel="stylesheet"
            href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
        />
        <link rel="stylesheet" type="text/css" href="{% static "css/index.css" %}"
        />
    </head>
    <body>
        <div id="main">
            <div id="app"></div>
        </div>
        <script src="{% static "frontend/main.js" %}"></script>
    </body>
</html>

 

 

13. frontend/views 작성

그리고 django views가 url에 맞춰서 html 날려주는 건 똑같고. 약간 이 views 부분이 react랑 django 다리 역할 느낌?

from django.shortcuts import render

# Create your views here.
def index(request, *args, **kwargs):
    return render(request, 'frontend/index.html')

 

 

14. settings.py에 생성한 앱 추가

    INSTALLED_APPS = [
    ...
    'frontend.apps.FrontendConfig',
    ]

 

 

15. python 서버와 npm 서버 실행

python manage.py runserver
npm run dev

** 그런데 WARNING in DefinePlugin Conflicting values for 'process.env.NODE_ENV' 에러가 발생해서 아래 webpack.config.js 부분을 바꿨음. 근데 이렇게 하면 번들이 무거워질 수 있다고, production으로 바꾸는 거 추천한다고 하는데.. 왜 생긴 에러인지를 아직 모르겠네.

 plugins: [
    new webpack.DefinePlugin({
        "process.env": {
        // This has effect on the react lib size
        NODE_ENV: JSON.stringify("development"),
        },
    }),
    ],
};

https://stackoverflow.com/questions/66772358/webpack-warning-warning-in-defineplugin-conflicting-values-for-process-env-no

 

webpack warning - WARNING in DefinePlugin Conflicting values for 'process.env.NODE_ENV'

I'm getting the warning in the title when I try to run development mode. This script used to work fine for an earlier website but now I always get this warning. This is my package.json: { "n...

stackoverflow.com

 

 

* 정상적으로 react와 django 연결 완료

+ Recent posts