ABOUT ME

IT와 컴퓨터 관련 팁, 파이썬 등과 아파트 정보, 일상적인 경험 등의 생활 정보를 정리해서 올리는 개인 블로그

  • 파이썬 장고(django) 웹 프로그래밍 - 웹 페이지 만들기 # 2
    코딩 연습/코딩배우기 2021. 11. 3. 13:50
    반응형

     

    파이썬 장고(django) 웹 프로그래밍 - 웹 페이지 만들기 (2)

     

    12. products 앱 생성 

    - 상품 등록과 관리를 위한 products 앱 생성하기

    (venv) PS D:\borame> python manage.py startapp products

     

    - 앱 등록하기 : settings.py 에 'products' 추가

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'accounts',
        'products',
    ]

     

    - config>urls.py 에 경로 설정에 products 경로 추가

    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('accounts/', include('accounts.urls')),
        path('', include('products.urls')),
    ]

     

    - products 앱에 templates 폴더를 만들고 그 하위에 products 폴더를 만든다.

    * products>templates>products

     

    - products>urls.py 파일 생성, path 지정

    * app_name도 지정하고 views.py import 함

    from django.urls import path
    from . import views
    
    app_name = 'products'
    
    urlpatterns = [
        path('', views.index, name='index'),
    ]

     

    good4me.co.kr

     

     

    - views.py 에 index() 작성

    from django.shortcuts import render
    
    def index(request):
        return render(request, 'products/index.html')

     

    - localhost:8000으로 접속 시 index.html로 연결되도록 템플릿 파일 작성

    * products>templates>products>index.html

    {% extends 'base.html' %}
    {% block content %}
    <br>
    <h3>Products Page</h3>
    
    {% endblock %}

     

    - base.html의 Home에 URL 지정

    <li class="nav-item"><a class="nav-link active" aria-current="page" href="#">Home</a></li> 부분을

    <li class="nav-item"><a class="nav-link active" aria-current="page" href="{% url 'products:index' %}">Home</a></li> 로 수정

    * Home 클릭 시, products 앱에서 name이 index 인 path URL로 보내고, views.py의 index() 함수가 처리함

     

    - localhost:8000 접속 시, 아래 이미지가 보임(Home 클릭 시 또는 로그인/로그아웃 후에도 동일)

     

    - base.html의 Home에 URL 지정

     

     

    13. 쿠팡 파트너스 API 데이터 등록을 위한 products 앱 모델(models) - db 작성

    ※ 개인적으로 구상한 db 임

    • 적용할 사이트명(스마트스토어, 쿠팡, 쿠팡API)은 선택(Select) 리스트로 처리
    • 상품카테고리(코드와 이름)도 통일성과 오타 등의 오류 방지를 위해 Foreign Key로 db 적용
    • 상품카테고리는 추가 가능하나 쿠팡의 분류를 default로 함 

     

    - products models.py 

    from django.db import models
    
    
    class Product(models.Model):
        SITE_NAME = (
            ('smartstore', 'Smartstore'),
            ('coupang', 'Coupang'),
            ('coupapi', 'Coupang API'),
        )
    
        site_name = models.CharField(max_length=100, verbose_name='상품 사이트명', choices=SITE_NAME)
        product_name = models.CharField(max_length=200, verbose_name='상품명', help_text='상품 상세페이지의 상품 제목')
        product_url = models.CharField(max_length=1000, verbose_name='상품 Link URL', help_text='상품 상세페이지 URL Copy & Paste')
        category = models.ForeignKey('Category', on_delete=models.SET_NULL, null=True)
        product_image = models.CharField(max_length=1000, verbose_name='상품이미지 Link URL')
        product_no = models.CharField(max_length=30, verbose_name='상품번호(코드)', help_text='상품 각각의 고유번호')
        view_ox = models.BooleanField(verbose_name='사용자에게 보여주기', default=True, help_text=' (체크 시 보여줌)')
        hits = models.PositiveIntegerField(default=0, verbose_name='클릭 카운트')
        updated = models.DateTimeField(auto_now=True)
        product_rank = models.IntegerField(verbose_name='랭크', null=True, blank=True)
        product_content = models.TextField(verbose_name='상품내용(요약)', null=True, blank=True)
        etc1 = models.CharField(max_length=1000, verbose_name='비고1', null=True, blank=True)
        etc2 = models.CharField(max_length=1000, verbose_name='비고2', null=True, blank=True)
    
        def __str__(self):
            return self.product_name
    
        @property
        def click_counter(self):
            self.hits += 1
            self.save()
    
    
    class Category(models.Model):
        categ_code = models.CharField(max_length=10, verbose_name='카테고리 코드')
        categ_name = models.CharField(max_length=200, verbose_name='카테고리 분류 명칭')
    
        def __str__(self):
            return f'{self.categ_code} - {self.categ_name}'

    * category = models.ForeignKey('Category', on_delete=models.SET_NULL, null=True) 처럼 외래키(Foraign key) 지정 시 db 테이블에서는 category_id로 표시됨

    * table명은 products_product 처럼 "앱이름_모델명"으로 됨

     

    - models 마이그레이션 및 마이그레이트

    (venv) PS D:\borame> python manage.py makemigrations products
    Migrations for 'products':
      products\migrations\0001_initial.py
        - Create model Category
        - Create model Product
    (venv) PS D:\borame> python manage.py migrate products
    Operations to perform:
      Apply all migrations: products
    Running migrations:
      Applying products.0001_initial... OK
    (venv) PS D:\borame>

     

    * DB Browser for SQLite 설치하여 db 관리 (2개의 테이블 생성 확인)

     

     

    - admin에 앱 등록

    from django.contrib import admin
    from .models import Product, Category
    
    
    @admin.register(Product)
    class ProductAdmin(admin.ModelAdmin):
        list_display = ['id', 'category', 'site_name', 'product_name', 'view_ox', 'hits', 'updated']
        list_display_links = ['id', 'site_name', 'product_name']
        list_per_page = 30
    
    
    @admin.register(Category)
    class CategoryAdmin(admin.ModelAdmin):
        list_display = ['id', 'categ_code', 'categ_name']
        list_display_links = ['id', 'categ_code', 'categ_name']

     

     

    - admin 에 로그인 후 테스트 데이터 입력

    admin 로그인 후 Products 클릭

     

     

    ADD PRODUCT 클릭

     

     

    카테고리 입력

     

     

    14. index.html에서 입력 데이터 보이기

    - views.py 수정
    . index.html에서 등록 상품을 보여줄 때 카테고리 코드에 따라 보여주도록 할 것이며,
    . default는 일단 category_code 1001로 하고, 
    . 카테고리 선택 시 해당 카테고리 상품이 보이도록 한다.
    l. ocalhost:8000 접속 시 code 1001을 db에서 추출하여 템플릿에 전달하도록 index() 수정

    from django.shortcuts import render
    from .models import Product, Category
    
    
    def index(request):
        category = Category.objects.get(categ_code='1001')
        product_list = Product.objects.all().filter(category_id=category.id).order_by('-id')
        context = {'product_list': product_list}
        return render(request, 'products/index.html', context)

    . 카테고리 코드가 1001인 상품을 Product 모델에서 Queryset으로 가져오고 index.html 템플릿에 전달함

    . Product.objects.filter 의 filter() 는 sql query의 where 절에 해당

     

    - index.html 수정

    {% extends 'base.html' %}
    {% block content %}
    
    {% if product_list %}
    <div class="container">
        <div class="row" style="padding: 2px 0px">
        {% for prd in product_list %}
            {% if prd.view_ox %}
            <div class="col p-3 border bg-light">
                <p style="text-align:center;"><a href="{{ prd.product_url }}" target="_blank">
                    <img src="{{ prd.product_image }}" width="250"></a></p>
                <p><h4><a href="{{ prd.product_url }}" target="_blank">{{ prd.product_name }}</a></h4></p>
                <p><small style="color:silver">등록(수정): {{ prd.updated|date:"Y-m-d H:i:s" }}</small></p>
            </div>
            {% endif %}
        {% endfor %}
        </div>
    </div>
    
    {% else %}
    <div class="row">
        <div class="col-md-12 panel panel-default">
            <p>표시할 목록이 없습니다.</p>
        </div>
    </div>
    
    {% endif%}
    
    {% endblock %}

     

     

    반응형
Designed by goodthings4me.