#!/usr/bin/env python

# -*- coding: utf-8 -*-

import os, sys, django

sys.path.append(".")

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "demo.settings")

django.setup()

from brand.models import *

import json


class ProductDB():

  def __init__(self, model):

    self.model = model

  def create(self, pid, cat1id, cat2id, cat3id, pname, brand, imgurl):

    if self.model == Product:

      p = Product(pid=pid, cat1id=cat1id, cat2id=cat2id, cat3id=cat3id, pname=pname, brand=brand, imgurl=imgurl)

      p.save()


class DataFile():

  def __init__(self, fp):

    self.f = open(fp, 'r')

  def read(self):

    line = self.f.readline().strip()

    return line

  def json_data(self):

    line = self.f.readline().strip()

    data = json.loads(line)

    return data


def main():

  data_dir = "./data/json.txt"

  f = DataFile(data_dir)


  while(True):

    data = f.json_data()

    if not data:  break

    pid = data['id']

    cat1id = data['category1Id']

    cat2id = data['category2Id']

    cat3id = data['category3Id']

    pname = data['productName']

    brand = data['brand']

    imgurl = data['imageUrl']


    p = ProductDB(Product)

    p.create(pid, cat1id, cat2id, cat3id, pname, brand, imgurl)


####################################################

# main

####################################################

if __name__ == '__main__':

  main()



장고 bootstrap templates 활용해서 아이템 이쁘게 정돈하기

1. modulus (%) 연산 함수를 정의

vi templatetags/utils.py

# -*- coding: utf-8 -*-

from django.template.defaulttags import register


@register.filter

def mod( value, arg ):

  return value % arg

* templatetags 디렉토리 안에 __init__.py 파일 생성


2. 기본 html 수정

{% extends "brand/basic_frame.html" %}

{% block content %}

{% load utils %} 


<div class="pagination">

  <span class="step-links">

    <ul class="pagination">

    {% if contacts.has_previous %}

      <li><a href="?page={{ contacts.previous_page_number }}"> prev </a></li>

    {% endif %}

      <li><a href="#"> Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}. </a></li>

    {% if contacts.has_next %}

      <li><a href="?page={{ contacts.next_page_number }}"> next </a></li>

    {% endif %}

  </ul>

  </span>

</div>


<div class="container">

  {% for d in contacts %}

    {% ifequal forloop.counter|mod:3 0 %}

    <div class="row">

    {% endifequal %}

      <div class="col-sm-4">

        <div class="panel panel-success">

          <div class="panel-heading"> {{forloop.counter}} {{d.pname}}</div>

          <div class="panel-body"><img src="{{d.imgurl}}" class="img-responsive" style="width:100%" alt="Image"></div>

          <div class="panel-footer">{{d.brand}}</div>

        </div>

      </div>

    {% ifequal forloop.counter|mod:3 0 %}

    </div>

    {% endifequal %}

  {% endfor %}

</div><br>


{% endblock %}


3. 기본 html에서 동작 확인


1. Paginator 함수로 아이템 분할

vi views.py

# -*- coding: utf-8 -*-

from __future__ import unicode_literals


from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

from django.shortcuts import render

from django.views import View

from .models import *


# Create your views here.

class basic(View):

  def get(self, request, *args, **kwargs):

    #data = Product.objects.all()

    catid = '000006'

    if 'catid' in kwargs:

      catid = kwargs['catid']

    data = Product.objects.filter(cat1id=catid)


    # item number per page

    num_page = 10

    paginator = Paginator(data, num_page)

    page = request.GET.get('page')

    try:

      contacts = paginator.page(page)

    except PageNotAnInteger:

      # If page is not an integer, deliver first page.

      contacts = paginator.page(1)

    except EmptyPage:

      # If page is out of range (e.g. 9999), deliver last page of results.

      contacts = paginator.page(paginator.num_pages)


    return render(request, 'brand/basic.html', context={'catid':catid,'contacts':contacts})


2. 기본 html 에 pagination 생성

{% extends "brand/basic_frame.html" %}

{% block content %}


<div class="pagination">

  <span class="step-links">

    <ul class="pagination">

    {% if contacts.has_previous %}

      <li><a href="?page={{ contacts.previous_page_number }}"> prev </a></li>

    {% endif %}

      <li><a href="#"> Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}. </a></li>

    {% if contacts.has_next %}

      <li><a href="?page={{ contacts.next_page_number }}"> next </a></li>

    {% endif %}

  </ul>

  </span>

</div>


<div class="container-fluid bg-3 text-center">

  <div class="row">

    {% for d in contacts %}

    <div class="col-sm-4">

      <div class="media">

        <div class="media-left media-middle">

          <img src="{{d.imgurl}}" class="media-object" width="100" height="100">

        </div>

        <div class="media-body">

          <h4> {{d.pname}} </h4>

          <p> {{d.brand}} </p>

        </div>

      </div>

    </div>

    {% endfor %}

  </div>

</div>


{% endblock %}


3. pagination 동작 확인




- Reference

https://www.w3schools.com/bootstrap/bootstrap_pagination.asp

1. 기본 프레임 html에 드롭다운 생성

cd demo ($app_name)

vi templates/demo/basic_frame.html

<!DOCTYPE html>

<html>

  <head>

    <title>Shop Demo</title>


    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

  </head>

  <body>

    <nav class="navbar navbar-inverse" role="navigation">

    <div class="container">

      <div class="navbar-header">

        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false">

          <span class="sr-only">Toggle navigation</span>

          <span class="icon-bar"></span>

          <span class="icon-bar"></span>

          <span class="icon-bar"></span>

        </button>

        <a class="navbar-brand" href="#">Brand Demo</a>

      </div>

    </div>

    </nav>


    <div class="container">

      <div class="dropdown">

        <button class="btn btn-default dropdown-toggle" type="button" id="menu1" data-toggle="dropdown">Category

          <span class="caret"></span></button>

        <ul class="dropdown-menu" role="menu" aria-labelledby="menu1">

          <li role="presentation"><a role="menuitem" tabindex="-1" href="/basic/000004">문방구</a></li>

          <li role="presentation"><a role="menuitem" tabindex="-1" href="/basic/000006">패션의류</a></li>

          <li role="presentation"><a role="menuitem" tabindex="-1" href="/basic/000010">책/잡지</a></li>

          <li role="presentation"><a role="menuitem" tabindex="-1" href="/basic/000031">CD</a></li>

          <li role="presentation"><a role="menuitem" tabindex="-1" href="/basic/000041">키친용품</a></li>

          <li role="presentation"><a role="menuitem" tabindex="-1" href="/basic/000049">인테리어/가구</a></li>

          <li role="presentation"><a role="menuitem" tabindex="-1" href="/basic/000082">DIY</a></li>

          <li role="presentation"><a role="menuitem" tabindex="-1" href="/basic/000146">가전</a></li>

          <li role="presentation"><a role="menuitem" tabindex="-1" href="/basic/000162">컴퓨터</a></li>

          <li role="presentation"><a role="menuitem" tabindex="-1" href="/basic/000174">일상용품/생활용품</a></li>

        </ul>

      </div>

    </div>


    <div class="container">

      <div class="row">

        {% block content %}{% endblock %}

      </div>

    </div>

  </body>

</html>


2. 기본 html 작성

vi templates/demo/basic.html

{% extends "brand/basic_frame.html" %}

{% block content %}


<div class="container-fluid bg-3 text-center">

  <div class="row">

    {% for d in data%}

    <div class="col-sm-4">

      <div class="media">

        <div class="media-left media-middle">

          <img src="{{d.imgurl}}" class="media-object" width="100" height="100">

        </div>

        <div class="media-body">

          <h4> {{d.pname}} </h4>

          <p> {{d.brand}} </p>

        </div>

      </div>

    </div>

    {% endfor %}

  </div>

</div>


{% endblock %}


3. 드롭다운에서 얻는 카테고리 id (href="/basic/000004") url 주소로 파싱

vi urls.py

from django.conf.urls import url

from . import views


urlpatterns = [

  url(r'^basic/$',views.basic.as_view(), name='basic'),

  url(r'^basic/(?P<catid>[-\w]+)/$',views.basic.as_view(), name='basic'),

]


4. url 주소에서 얻은 카테고리 id의 데이터 반영

vi views.py

# -*- coding: utf-8 -*-

from __future__ import unicode_literals


from django.shortcuts import render

from django.views import View

from .models import *


# Create your views here.

class basic(View):

  def get(self, request, *args, **kwargs):

    #data = Product.objects.all()

    catid = '000006'

    if 'catid' in kwargs:

      catid = kwargs['catid']

    data = Product.objects.filter(cat1id=catid)


    return render(request, 'brand/basic.html', context={'catid':catid,'data':data})


5. 드롭다운 동작 확인

https://~:8080/basic





- Reference

https://www.w3schools.com/bootstrap/bootstrap_dropdowns.asp

1. html 에서 css 정의하여 사용하기

vi templates/demo/base.html

<!doctype html>

<html lang="en">

  <head>

    <title>MyDjangoApp</title>


    <meta charset="utf-8">

    <meta name="viewport" content="width=device-width, initial-scale=1">


    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

  </head>

  <body class="override">

    <nav class="navbar navbar-inverse" role="navigation">

    <div class="container">

      <div class="navbar-header">

        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false">

          <span class="sr-only">Toggle navigation</span>

          <span class="icon-bar"></span>

          <span class="icon-bar"></span>

          <span class="icon-bar"></span>

        </button>

        <a class="navbar-brand" href="#">Django Pagination</a>

      </div>

    </div>

    </nav>


    <div class="container">

      <div class="row">

        {% block content %}{% endblock %}

      </div>

    </div>

  </body>

</html>


vi templates/demo/home.html

{% extends "demo/base.html" %}


{% block content %}

<div class="container products-view-user">

  {% csrf_token %}

  <form class = "post-list">

    <input type = "hidden" value = "" />

  </form>

  <article class="navbar-form navbar-left p-0 m-0 ml-b">

  <div class="form-group">

    <label>Per Page: </label>

    <select class="form-control post_max">

      <option value="1">1</option>

      <option value="2">2</option>

      <option value="3">3</option>

    </select>

    <label>Search Keyword: </label>

    <input type="text" class="form-control post_search_text" placeholder="Enter a keyword">

  </div>

  <input type = "submit" value = "Filter" class = "btn btn-primary post_search_submit" />

  </article>


  <a href="user-products-add.php" class="btn btn-success pull-right">Add New</a>


  <br class = "clear" />


  <div class = "wave-box-wrapper">

    <div class = "wave-box"></div>

    <table class = "table table-striped table-post-list no-margin">

      <thead>

        <tr>

          <th>Image</th>

          <th>Id</th>

          <th>Name</th>

          <th>Brand</th>

          <th>cat1id</th>

          <th>cat2id</th>

          <th>cat3id</th>

        </tr>

      </thead>

      <tbody class = "pagination-container">

        {% for d in data %}

        <tr>

          <td> <img src="{{d.imgurl}}" width="100" height="100"> </td>

          <td> {{d.pid}} </td>

          <td> {{d.pname}} </td>

          <td> {{d.brand}} </td>

          <td> {{d.cat1id}} </td>

          <td> {{d.cat2id}} </td>

          <td> {{d.cat3id}} </td>

        </tr>

        {% endfor %}

      </tbody>

    </table>


    <div class = "pagination-nav"></div>

  </div>

</div>

{% endblock %}


2. 기본 홈페이지에서 확인

http://~:8080/home




- Reference -

Python – Django AJAX Pagination with Search and Sort [Tutorial]

1. 장고 뷰에서 데이터 베이스 paginator로 설정 

cd demo

vi views.py

# -*- coding: utf-8 -*-

from __future__ import unicode_literals


from django.shortcuts import render

from django.views import View

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger


from .models import *


# Create your views here.

class catetc_base(View):

  def get(self, request, *args, **kwargs):

    products = Product.objects.all()

    # 한 페이지에 보여줄 아이템 개수

    page_item_num = 5

    paginator = Paginator(products, page_item_num)

    page = request.GET.get('page')

    items = None

    try:

      items = paginator.page(page)

    except PageNotAnInteger:

      items = paginator.page(1)

    except EmptyPage:

      items = paginator.page(paginator.num_pages)


    return render(request, 'demo/demo_base.html', context={'items':items})


2. html 에서 페이지 표시 구현

vi templates/demo/demo_base.html

<!doctype html>

<html lang="ko">

<html>

  <head>

    <meta charset="utf-8">

    <title>Paginator Demo</title>

  </head>


  <body>

    <a>Products</a> <br>

    <table>

      <thead>

        <tr>

          <th> pid    </th>

          <th> cat1id </th>

          <th> cat2id </th>

          <th> cat3id </th>

          <th> pname  </th>

          </tr>

      </thead>

      <tbody>

        {% for w in items %}

        <tr>

          <td> {{ w.pid }}    </td>

          <td> {{ w.cat1id }} </td>

          <td> {{ w.cat2id }} </td>

          <td> {{ w.cat3id }} </td>

          <td> {{ w.pname }}  </td>

        </tr>

        {% endfor %}

      </tbody>

    </table>


    <div class="pagination">

    <span class="step-links">

      {% if items.has_previous %}

        <a href="?page={{ items.previous_page_number }}{% for key, value in request.GET.items %}{% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}">previous</a>

      {% endif %}

      <span class="current">

        Page {{ items.number }} of {{ items.paginator.num_pages }}.

      </span>

      {% if items.has_next %}

        <a href="?page={{ items.next_page_number }}{% for key, value in request.GET.items %}{% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}"> next </a> &nbsp

      {% endif %}

    </span>

    </div>

  </body>

</html>


1. 템플릿태그 폴더에 사용할 함수 생성

cd demo

mkdir templatetags

vi templatetags/util.py

# -*- coding: utf-8 -*-

from django.template.defaulttags import register


@register.filter

def div( value, arg ):

  '''

  Divides the value; argument is the divisor.

  Returns empty string on any error.

  '''

  try:

    value = int( value )

    arg = int( arg )

    if arg: return value / arg

  except: pass

  return ''


2. html 에 템플릿태그 함수 로드 후 사용

vi templates/demo/demo_base.html

<!doctype html>

{% load util %}


<html lang="ko">

<html>

  <head>

    <meta charset="utf-8">

    <title>Templatetags Demo</title>

  </head>

  <body>

    10 / 2 = {{ 10|div:2 }}

   </body>

</html>

* html templatetags format : $value | ${func_name} : $arg


3. 마이그레이션 하기  (make migration)

cd ..

python manage.py makemigrations demo

python manage.py migrate


4. 기본 홈페이지에서 결과 확인

* 서버를 리셋해줘야함

10 / 2 = 5


<menu 프레임에서 상품 ID를 클릭하면 content 프레임에서 상품 정보를 보여주는 예제>

* 기존 튜토리얼 app name의 demo를 catetc로 변경하여 진행


1. 웹 프레임 menu 페이지에 데이터 베이스 pid 연동

[데이터 베이스] http://poorman.tistory.com/384

vi views.py

# -*- coding: utf-8 -*-

from __future__ import unicode_literals


from django.shortcuts import render

from django.views import View


from .models import *


# Create your views here.

class catetc_base(View):

  def get(self, request, *args, **kwargs):

    return render(request, 'catetc/catetc_base.html', context={})


class catetc_title(View):

  def get(self, request, *args, **kwargs):

    return render(request, 'catetc/catetc_title.html', context={})


class catetc_menu(View):

  def get(self, request, *args, **kwargs):

    products = Product.objects.all()

    return render(request, 'catetc/catetc_menu.html', context={'products':products})


class catetc_content(View):

  def get(self, request, *args, **kwargs):

    return render(request, 'catetc/catetc_content.html', context={})


2. 웹 프레임 content 페이지에서 pid (상품id) 전달 받을 수 있도록 url 설정

 vi urls.py

from django.conf.urls import url

from . import views


urlpatterns = [

  url(r'^catetc/$',views.catetc_base.as_view(), name='catetc_base'),

  url(r'^catetc/title/$',views.catetc_title.as_view(), name='catetc_title'),

  url(r'^catetc/menu/$',views.catetc_menu.as_view(), name='catetc_menu'),

  url(r'^catetc/content/$',views.catetc_content.as_view(), name='catetc_content'),

  url(r'^catetc/content/(?P<pid>[-\w]+)/$',views.catetc_content.as_view(), name='catetc_content'),

]


3. menu 프레임에서 content 프레임으로 pid 전달하도록 설정

vi templates/catetc/catetc_menu.html

<!doctype html>

<html lang="ko">

<html>

  <head>

    <meta charset="utf-8">

    <title>Category Demo</title>

  </head>

  <body>

    <a>Menu Product Ids</a> <br>

    {% for p in products %}

      <a href="{% url 'catetc_content' pid=p.pid %}" target='content'> {{ p.pid }} </a> <br>

    {% endfor %}

  </body>

</html>


4. content 프레임으로 pid 가 전달된 경우에 상품 데이터 베이스를 읽어들임

# -*- coding: utf-8 -*-

from __future__ import unicode_literals


from django.shortcuts import render

from django.views import View


from .models import *


# Create your views here.

class catetc_base(View):

  def get(self, request, *args, **kwargs):

    return render(request, 'catetc/catetc_base.html', context={})


class catetc_title(View):

  def get(self, request, *args, **kwargs):

    return render(request, 'catetc/catetc_title.html', context={})


class catetc_menu(View):

  def get(self, request, *args, **kwargs):

    products = Product.objects.all()

    return render(request, 'catetc/catetc_menu.html', context={'products':products})


class catetc_content(View):

  def get(self, request, *args, **kwargs):

    if 'pid' in kwargs:

      pid = kwargs['pid']

      prod = Product.objects.get(pid=pid)

      return render(request, 'catetc/catetc_content.html', context={'prod':prod})

    else:

      return render(request, 'catetc/catetc_content.html', context={})


5. content 프레임에서 상품 정보 표시

vi templates/catetc/catetc_content.html

<!doctype html>

<html lang="ko">

<html>

  <head>

    <meta charset="utf-8">

    <title>Category Demo</title>

  </head>

  <body>

    <a>Product Info</a> <br>

    <table>

      <thead>

        <tr>

          <th> pid    </th>

          <th> cat1id </th>

          <th> cat2id </th>

          <th> cat3id </th>

          <th> pname  </th>

          </tr>

      </thead>

      <tbody>

        <tr>

          <td> {{ prod.pid }}    </td>

          <td> {{ prod.cat1id }} </td>

          <td> {{ prod.cat2id }} </td>

          <td> {{ prod.cat3id }} </td>

          <td> {{ prod.pname }}  </td>

        </tr>

      </tbody>

    </table>

    </body>

</html>


6. 기본 홈페이지에서 프레임 동작 확인

http://~:8080/catetc


1. 프레임 별의 urls , views 설정

cd demo

vi urls.py

from django.conf.urls import url

from . import views


urlpatterns = [

  url(r'^demo/$',views.demo_base.as_view(), name='demo_base'),

  url(r'^demo/title$',views.demo_title.as_view(), name='demo_title'),

  url(r'^demo/menu$',views.demo_menu.as_view(), name='demo_menu'),

  url(r'^demo/content$',views.demo_content.as_view(), name='demo_content'),

]

vi views.py

# -*- coding: utf-8 -*-

from __future__ import unicode_literals


from django.shortcuts import render

from django.views import View


from .models import *


# Create your views here.

class demo_base(View):

  def get(self, request, *args, **kwargs):

    return render(request, 'demo/demo_base.html', context={})


class demo_title(View):

  def get(self, request, *args, **kwargs):

    return render(request, 'demo/demo_title.html', context={})


class demo_menu(View):

  def get(self, request, *args, **kwargs):

    return render(request, 'demo/demo_menu.html', context={})


class demo_content(View):

  def get(self, request, *args, **kwargs):

    return render(request, 'demo/demo_content.html', context={})


2. 기본 홈페이지의 프레임 나누기

vi templates/demo/demo_base.html

<!doctype html>

<html lang="ko">

<html>

  <head>

    <meta charset="utf-8">

    <title>Demo</title>

  </head>

  <frameset rows="20%,*">

    <frame src="title"/>

      <frameset cols="30%,*">

        <frame src="menu" name="menu"/>

        <frame src="content" name="content"/>

      </frameset>

  </frameset>

</html>


3. 각 프레임에 표시할 내용 설정

vi templates/demo/demo_title.html

<!doctype html>

<html lang="ko">

<html>

  <head>

    <meta charset="utf-8">

    <title>Demo Title</title>

  </head>

  <body>

    <a>Title</a>

  </body>

</html>

vi templates/demo/demo_menu.html

<!doctype html>

<html lang="ko">

<html>

  <head>

    <meta charset="utf-8">

    <title>Demo menu</title>

  </head>

  <body>

    <a>Menu</a>

  </body>

</html>

vi templates/demo/demo_content.html

<!doctype html>

<html lang="ko">

<html>

  <head>

    <meta charset="utf-8">

    <title>Demo Content</title>

  </head>

  <body>

    <a>Content</a>

  </body>

</html>


4. 기본 홈페이지에서 프레임 내용 확인

http://~:8080/demo


1. 데이터 베이스 전달

cd demo

vi views.py

# -*- coding: utf-8 -*-

from __future__ import unicode_literals


from django.shortcuts import render

from django.views import View

from .models import *


# Create your views here.

class catetc_base(View):

  def get(self, request, *args, **kwargs):

    data = Product.objects.all()

    return render(request, 'catetc/catetc_base.html', context={'data':data})


2. html 에서 데이터 베이스 표시

vi templates/demo/demo_base.html

<!doctype html>

<html lang="ko">

<html>

  <head>

    <meta charset="utf-8">

    <title>Category Demo</title>

  </head>


  <body>

    <table>

      <thead>

        <tr>

          <th> pid    </th>

          <th> cat1id </th>

          <th> cat2id </th>

          <th> cat3id </th>

          <th> pname  </th>

          </tr>

      </thead>

      <tbody>

        {% for w in data %}

        <tr>

          <td> {{ w.pid }}    </td>

          <td> {{ w.cat1id }} </td>

          <td> {{ w.cat2id }} </td>

          <td> {{ w.cat3id }} </td>

          <td> {{ w.pname }}  </td>

        </tr>

        {% endfor %}

      </tbody>

    </table>

  </body>


</html>


3. 기본 홈페이지에서 데이터 확인

http://~:8080/demo


+ Recent posts