Table generate guide - pai-plznw4me/django-initializer GitHub Wiki

Table ์ƒ์„ฑ ํ‘œ์ค€ ๊ฐ€์ด๋“œ

๋ชฉ์ฐจ

table ์กฐ์ž‘์‹œ DataFrame from db -> preprocessing -> table html design -> insert base code ์ˆœ์„œ๋กœ ๊ฐœ๋ฐœํ•œ๋‹ค.

  1. DataFrame from db

  2. preprocessing

  3. table html design

  4. insert base code

โš ๏ธ๊ด€๋ จ libarary ๋Š” html_helper ๋ชจ๋‘ ์ •์˜๋˜์–ด ์žˆ๋‹ค.

0.์ด์œ 

html ์„ django template ์„ ์•ˆ์“ฐ๊ณ  python ์œผ๋กœ ์ œ์–ด ํ• ๋ ค๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ธ๊ฐ€? ์–ด๋–ค ์žฅ์ ์ด ์žˆ๋Š”๊ฐ€?

  • django ์— ์ข…์†๋œ๋‹ค.
  • ํ‘œ์ค€ํ™” ์ฝ”๋“œ๋กœ ๋งŒ๋“ค๊ธฐ ํž˜๋“ค๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ์—๊ฒŒ ๊ต์œกํ•˜๊ธฐ ํž˜๋“ค๋‹ค.
  • ๊ฐœ๋ฐœ layer ๊ฐ€ ๋ณต์žกํ•ด์ง„๋‹ค.
    • python โ†” html ์œผ๋กœ ์™”๋‹ค ๊ฐ”๋‹ค ํ•˜๋ฉด์„œ ์ฝ”๋”ฉํ•˜๋ฉด ์ง‘์ค‘์„ฑ , ํšจ์œจ์„ฑ์ด ๋งŽ์ด ๋–จ์–ด์ง„๋‹ค.
  • debugging ์ด ์šฉ์ดํ•˜๋‹ค
    • django ์„ ํ‹€ ํ•„์š”์—†์ด ๋ฐ”๋กœ html ๋กœ ์ €์žฅํ•ด์„œ ํ™•์ธ ๊ฐ€๋Šฅ, ํ–‰๋ณต ์‹œ์ž‘

1. DataFrame from DB

  • ์•„๋ž˜์™€ ๊ฐ™์ด db ์กฐํšŒ๋ฅผ ํ•œํ›„์— Dataframe ์œผ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.
def index(request):
    files = File.objects.all()
    files_df = pd.DataFrame.from_records(files.values())
    files_html = files_df.to_html()
    return HttpResponse(files_html)
  • HttpResponse ์„ ํ™œ์šฉํ•ด ๋ฐ”๋กœ html ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

table_output

๊ทธ๋Ÿผ ์ด๋ ‡๊ฒŒ ๋ฐ”๋กœ table ์ด ๋‚˜์˜จ๋‹ค.

2. Table Preprocessing

table ์„ ์กฐ์ž‘ ์ œ์–ด ํ•œ๋‹ค.

2.1 ํŠน์ • ์—ด๋งŒ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์„๋•Œ

  • field ํ•ญ๋ชฉ์€ forms ์—์„œ ๊ด€๋ฆฌํ•œ๋‹ค.

  • ์•„๋ž˜์™€ ๊ฐ™์ด Form ์„ ๋งŒ๋“ค๊ณ  Form.Meta.fields ์„ ํ†ตํ•ด ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค

  • class FileShowForm(forms.ModelForm):
        class Meta:
            model = File
            fields = ['id',
                      'name',
                      # 'ext',
                      'size',
                      # 'upload_date',
                      'creation_date',
                      'version',
                      'project',
                      'filecontent',
                      'authority']
    
            widgets = {
                'creation_date': forms.widgets.DateInput(attrs={'type': 'date'})
            }
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
    
  • ์ดํ›„

def index(request):
    files = File.objects.all()
    show_fields = FileShowForm.Meta.fields
    files_df = pd.DataFrame.from_records(files.values())
    target_files_df = files_df.loc[:, show_fields] #<-- ์—ฌ๊ธฐ๋ฅผ ๋ณด์ž 
    files_html = target_files_df.to_html()
    return HttpResponse(files_html)

3. Table ๋””์ž์ธ

4. insert base code ์ˆœ์„œ๋กœ ๊ฐœ๋ฐœํ•œ๋‹ค.

Table ์†์„ฑ ๋ณ€๊ฒฝ

table ๋‚ด ํƒœ๊ทธ ์‚ฝ์ž…

wrap_with_tag ์„ ํ™œ์šฉ

Table codeing

import pandas as pd
from bs4 import BeautifulSoup
import numpy as np


def save_as_html(path, html):
    """
    ์ฃผ์–ด์ง„ HTML ํƒœ๊ทธ๋ฅผ ํŒŒ์ผ๋กœ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

    ๋งค๊ฐœ๋ณ€์ˆ˜:
        - path (str): HTML ๋‚ด์šฉ์„ ์ €์žฅํ•  ํŒŒ์ผ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค.
        - tags (str): ์ €์žฅํ•  HTML ํƒœ๊ทธ ๋˜๋Š” ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

    ์˜ˆ์‹œ:
        save_as_html('output.html', '<p>Hello, World!</p>')
    """
    with open(path, 'w', encoding='utf-8') as f:
        f.write(html)


def wrap_with_tag(input_string, tag_name, **attr):
    """
      ์ฃผ์–ด์ง„ ๋ฌธ์ž์—ด์„ ์ง€์ •ํ•œ HTML ํƒœ๊ทธ๋กœ ๊ฐ์‹ธ๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

      Parameters:
          - input_string (str): ๊ฐ์Œ€ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค.
          - tag_name (str): ์ƒ์„ฑํ•  ํƒœ๊ทธ์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
          - **attr: ์ƒ์„ฑํ•  ํƒœ๊ทธ์˜ ๋‹ค๋ฅธ ์†์„ฑ์„ ์ง€์ •ํ•˜๋Š” ํ‚ค์›Œ๋“œ ์ธ์ž๋“ค์ž…๋‹ˆ๋‹ค.

      Returns:
          str: HTML ํƒœ๊ทธ๋กœ ๊ฐ์‹ธ์ง„ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค.

      Example:
          wrap_with_tag('<p>Hello, World!</p>', 'a', href='https://example.com', class_='link')
    """

    # BeautifulSoup์œผ๋กœ HTML ํŒŒ์‹ฑ
    soup = BeautifulSoup(input_string, 'html.parser')

    # <a> ํƒœ๊ทธ ์ƒ์„ฑ
    target_tag = soup.new_tag(name=tag_name, **attr)

    # ์›๋ž˜์˜ ๋ฌธ์ž์—ด์„ <a> ํƒœ๊ทธ ์•ˆ์œผ๋กœ ์˜ฎ๊ธฐ๊ธฐ
    target_tag.append(soup.new_string(input_string))

    # ์›๋ž˜์˜ ๋ฌธ์ž์—ด์„ <a> ํƒœ๊ทธ๋กœ ๋Œ€์ฒด
    soup.contents = [target_tag]

    # ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜
    return str(soup)


def add_css():
    pass


def add_js():
    pass


def html_load(basepath):
    """
       ์ฃผ์–ด์ง„ ํŒŒ์ผ ๊ฒฝ๋กœ์—์„œ HTML ํŒŒ์ผ์„ ์ฝ์–ด์™€ ๋ฌธ์ž์—ด๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

       Parameters:
           - basepath (str): ์ฝ์–ด์˜ฌ HTML ํŒŒ์ผ์˜ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค.

       Returns:
           str: HTML ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ ๋‹ด์€ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค.

       Example:
           html_content = html_load('path/to/your/file.html')
       """
    with open(basepath, 'r', encoding='utf-8') as f:
        html_content = f.read()
        return html_content


def bs4_load(base_path):
    """
    ์ฃผ์–ด์ง„ ํŒŒ์ผ ๊ฒฝ๋กœ์—์„œ HTML ํŒŒ์ผ์„ ์ฝ์–ด์™€ BeautifulSoup ๊ฐ์ฒด๋กœ ํŒŒ์‹ฑํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

    Parameters:
        - base_path (str): ์ฝ์–ด์˜ฌ HTML ํŒŒ์ผ์˜ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค.

    Returns:
        BeautifulSoup: HTML์„ ํŒŒ์‹ฑํ•œ BeautifulSoup ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

    Example:
        soup = bs4_load('path/to/your/file.html')
    """
    html_str = html_load(base_path)
    soup = BeautifulSoup(html_str, 'html.parser')
    return soup


if __name__ == '__main__':
    arr = np.arange(12).reshape(4, 3)
    df = pd.DataFrame(arr)
    df = df.applymap(lambda x: wrap_with_tag(str(x), tag_name='a', href='http://naver.com'))

    # ์…€ ๋‚ด html ์ฝ”๋“œ๋ฅผ html๋กœ ์ธ์‹ํ•œ๋‹ค. escape=True ์ด๋ฉด ๋ฌธ์ž์—ด๋กœ ์ธ์‹์„ ํ•œ๋‹ค. 
    table_html = df.to_html(escape=False)

    # base html ์„ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.
    base_soup = bs4_load('../base_template/bootstrap.html')

    # base html ๋‚ด table์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.
    body_tag = base_soup.find('body')
    first_script_tag = body_tag.find('script')
    first_script_tag.insert_before(table_html)

    # html ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
    save_as_html('temp.html', base_soup.prettify(formatter=None)) 
    # formatter ์„ None ์œผ๋กœ ํ•˜๋ฉด ํŠน์ˆ˜ ๊ธฐํ˜ธ๋“ค์ด ๋‚˜ $gt ์ด๋Ÿฐ ์‹์œผ๋กœ ๋‚˜์˜จ๋‹ค.