Django2 (8. 상품 등록하기) feat.페스트캠퍼스

min seung moon·2021년 3월 16일
0

Django

목록 보기
24/37

상품 등록하기(1)

01. product에 forms.py 만들기!

from django import forms
from .models import Product


class RegisterForm(forms.Form):
    name = forms.CharField(
        error_messages={
            'required': '상품명을 입력해주세요'
        },
        max_length=64, label='상품명'
    )
    price = forms.IntegerField(
        error_messages={
            'required': '상품가격을 입력해주세요'
        }, label='상품가격'
    )
    description = forms.CharField(
        error_messages={
            'required': '상품설명을 입력해주세요'
        }, label='상품설명'
    )
    stock = forms.IntegerField(
        error_messages={
            'required': '재고를 입력해주세요.'
        }, label='재고'
    )

    # validate
    def clean(self):
        cleaned_data = super().clean()
        name = cleaned_data.get('name')
        price = cleaned_data.get('price')
        description = cleaned_data.get('description')
        stock = cleaned_data.get('stock')

        if name and price and description and stock:
            product = Product(
                name=name,
                price=price,
                description=description,
                stock=stock
            )
            product.save()

02. register_product.html 수정!

{% extends "base.html" %}
{% block contents %}
<div class="row mt-5">
    <div class="col-12 text-center">
        <h1>상품 생성하기</h1>
    </div>
</div>
<div class="row mt-5">
    <div class="col-12">
        {{ error }}
    </div>
</div>
<div class="row mt-5">
    <div class="col-12">
        <form method="POST" action=".">
            {% csrf_token %}
            <!-- 커스터마이징 -->
            <!-- form을 반복문에 넣으면 각 필드별로 나온다 -->
            {% for field in form %}
            <div class="form-group">
                <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                {% ifequal field.name 'description' %}
                <textarea class="form-control" name="{{ field.name }}" id="{{ field.id_for_label }}"></textarea>
                {% else %}
                <input type="{{ field.field.widget.input_type }}" class="form-control" id="{{ field.id_for_label }}"
                    placeholder="{{ field.label }}" name="{{ field.name }}" />
                {% endifequal %}
            </div>
            {% if field.errors %}
            <span style="color: red">{{ field.errors }}</span>
            {% endif %}
            {% endfor %}
            <button type="submit" class="btn btn-primary">생성</button>
        </form>
    </div>
</div>
{% endblock %}

03. product에 views.py 수정!

from django.shortcuts import render
from django.views.generic import ListView
from django.views.generic.edit import FormView
from .models import Product
from .forms import RegisterForm

# Create your views here.


class ProductList(ListView):
    model = Product
    template_name = 'product.html'
    # object_list로 사용하기 싫으면 context_object_name으로 변경 가능
    context_object_name = 'product_list'


class ProductCreate(FormView):
    template_name = 'register_product.html'
    form_class = RegisterForm
    success_url = '/product/'

04. root 폴더에 urls.py에 등록하기!

  • path('url',modul)에서 url을 입력할 때 마지막에 꼭 / 넣어주기!
from django.contrib import admin
from django.urls import path
from fcuser.views import index, RegisterView, LoginiView
from product.views import ProductList, ProductCreate

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', index),
    # class는 .as_view()를 입력!
    path('register/', RegisterView.as_view()),
    path('login/', LoginiView.as_view()),
    path('product/', ProductList.as_view()),
    path('product/create/', ProductCreate.as_view()),
]

상품 등록하기(2)

01. base.html 수정하기!

  • root폴더의 settings.py를 보면 기본적으로 장고는 모든 app의 templates를 확인한다!
  • APP_DIRS가 TRUE이면 앱 디렉토리를 접근을 허용한다는 것이다!
  • 실질적으로 우리가 html을 작성할 때 extends를 하는 base.html은 각 앱의 base.html이 아닌다!
  • 실질적으로 상속받는 base.html은 fcuser의 base.html이다!
  • 그렇기에 product에 있는 base.html은 삭제해줘도 된다!

02. summernote 사용하기!

https://summernote.org/

  • easy to install 접근!
  • cdn 방식으로 사용할 거에요!
  • 현재 summernote가 bootstrap 버전 4에 맞춰져 있기때문에! base.html의 bootstrap 버전 다운 그레이드 하기!
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, inital-scale=1">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"
        integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
        integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous">
    </script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous">
    </script>
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
        integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous">
    </script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
        integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous">
    </script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js"
        integrity="sha384-+YQ4JLhjyBLPDQt//I+STsc9iw4uQqACwlvpslubQzn4u2UU2UFM80nGisd026JF" crossorigin="anonymous">
    </script>
</head>

<body>
    <div class="container">
        {% block contents %}
        {% endblock %}
    </div>
</body>

</html>


  • summernote는 필요한 페이지에서만 사용할것이기 때문에 base.html에 header block 생성!
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, inital-scale=1">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"
        integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
        integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous">
    </script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous">
    </script>
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
        integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous">
    </script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
        integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous">
    </script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js"
        integrity="sha384-+YQ4JLhjyBLPDQt//I+STsc9iw4uQqACwlvpslubQzn4u2UU2UFM80nGisd026JF" crossorigin="anonymous">
    </script>
    {% block header %}
    {% endblock %}
</head>

<body>
    <div class="container">
        {% block contents %}
        {% endblock %}
    </div>
</body>

</html>

  • register_product에 summernote cdn 처리하기!
{% extends "base.html" %}
{% block header %}
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-bs4.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-bs4.min.js"></script>
{% endblock %}
{% block contents %}
<div class="row mt-5">
    <div class="col-12 text-center">
        <h1>상품 생성하기</h1>
    </div>
</div>
<div class="row mt-5">
    <div class="col-12">
        {{ error }}
    </div>
</div>
<div class="row mt-5">
    <div class="col-12">
        <form method="POST" action=".">
            {% csrf_token %}
            <!-- 커스터마이징 -->
            <!-- form을 반복문에 넣으면 각 필드별로 나온다 -->
            {% for field in form %}
            <div class="form-group">
                <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                {% ifequal field.name 'description' %}
                <textarea class="form-control" name="{{ field.name }}" id="{{ field.id_for_label }}"></textarea>
                {% else %}
                <input type="{{ field.field.widget.input_type }}" class="form-control" id="{{ field.id_for_label }}"
                    placeholder="{{ field.label }}" name="{{ field.name }}" />
                {% endifequal %}
            </div>
            {% if field.errors %}
            <span style="color: red">{{ field.errors }}</span>
            {% endif %}
            {% endfor %}
            <button type="submit" class="btn btn-primary">생성</button>
        </form>
    </div>
</div>
{% endblock %}

  • summernote 적용시키기!
    • id가 #summernote로 되어 있기 때문에 우리에게 맞는 id로 변경!
{% extends "base.html" %}
{% block header %}
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-bs4.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-bs4.min.js"></script>
<script>
    $(document).ready(function () {
        $('#id_description').summernote();
    });
</script>
{% endblock %}
{% block contents %}
<div class="row mt-5">
    <div class="col-12 text-center">
        <h1>상품 생성하기</h1>
    </div>
</div>
<div class="row mt-5">
    <div class="col-12">
        {{ error }}
    </div>
</div>
<div class="row mt-5">
    <div class="col-12">
        <form method="POST" action=".">
            {% csrf_token %}
            <!-- 커스터마이징 -->
            <!-- form을 반복문에 넣으면 각 필드별로 나온다 -->
            {% for field in form %}
            <div class="form-group">
                <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                {% ifequal field.name 'description' %}
                <textarea class="form-control" name="{{ field.name }}" id="{{ field.id_for_label }}"></textarea>
                {% else %}
                <input type="{{ field.field.widget.input_type }}" class="form-control" id="{{ field.id_for_label }}"
                    placeholder="{{ field.label }}" name="{{ field.name }}" />
                {% endifequal %}
            </div>
            {% if field.errors %}
            <span style="color: red">{{ field.errors }}</span>
            {% endif %}
            {% endfor %}
            <button type="submit" class="btn btn-primary">생성</button>
        </form>
    </div>
</div>
{% endblock %}



  • summernote의 높이 높이기!
{% extends "base.html" %}
{% block header %}
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-bs4.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-bs4.min.js"></script>
<script>
    $(document).ready(function () {
        $('#id_description').summernote({
            height: 300
        });
    });
</script>
{% endblock %}
{% block contents %}
<div class="row mt-5">
    <div class="col-12 text-center">
        <h1>상품 생성하기</h1>
    </div>
</div>
<div class="row mt-5">
    <div class="col-12">
        {{ error }}
    </div>
</div>
<div class="row mt-5">
    <div class="col-12">
        <form method="POST" action=".">
            {% csrf_token %}
            <!-- 커스터마이징 -->
            <!-- form을 반복문에 넣으면 각 필드별로 나온다 -->
            {% for field in form %}
            <div class="form-group">
                <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                {% ifequal field.name 'description' %}
                <textarea class="form-control" name="{{ field.name }}" id="{{ field.id_for_label }}"></textarea>
                {% else %}
                <input type="{{ field.field.widget.input_type }}" class="form-control" id="{{ field.id_for_label }}"
                    placeholder="{{ field.label }}" name="{{ field.name }}" />
                {% endifequal %}
            </div>
            {% if field.errors %}
            <span style="color: red">{{ field.errors }}</span>
            {% endif %}
            {% endfor %}
            <button type="submit" class="btn btn-primary">생성</button>
        </form>
    </div>
</div>
{% endblock %}


  • 상품 등록할 때 이미지도 같이 등록해보기!
  • 정상 저장 확인!
  • 상세보기 페이지가 없기 때문에 관리자 페이지에서 확인!
profile
아직까지는 코린이!

0개의 댓글

관련 채용 정보