standard index - pai-plznw4me/django-initializer GitHub Wiki

ํ‘œ์ค€ Index Page ๊ฐ€์ด๋“œ

0. Preโ€ขrequisite

1. manage.py ํŒŒ์ผ์ด ์žˆ๋Š” ํด๋” ๋‚ด `helper.py` ๊ฐ€ ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

2. templatetags

   |- index.py

3. templates/standard
   |-create.html
   |-detail.html
   |-update.html

1. What?

  • ํ‘œ์ค€ ์ธ๋ฑ์Šค๋Š” Target ๋ชจ๋ธ record ํ•ญ๋ชฉ๋“ค์„ ๋ณด์—ฌ์ฃผ๋Š” Html Page ์„ ๋œปํ•จ.
  • ํ‘œ์ค€ Index page ๋Š” standard_index() ์„ ํ†ตํ•ด ์ƒ์„ฑ๋œ ์ฝ”๋“œ ๋ฐ HTML ์„ ์˜๋ฏธํ•œ๋‹ค.
def standard_index(request, model, model_filter, form_class, url_path, base, crud_table, callback, **callback_kwargs):
    added_contents = []
    instances = model.objects.filter(**model_filter)

    # url
    full_url = request.build_absolute_uri()
    base_url = get_base_url(full_url)

    # crud standard table
    crud_table_html = crud_table(base_url, instances, form_class._meta.fields, url_path)
    added_contents.append(crud_table_html)

    # callback
    if callback:
        callback(request=request, model=model, model_filter=model_filter, form_class=form_class, url_path=url_path,
                 base=base, instances=instances, crud_table_html=crud_table_html, added_contents=added_contents,
                 **callback_kwargs)

    # render
    ret_html = add_content(request, base, *added_contents)
    return HttpResponse(ret_html)

์Šคํฌ๋ฆฐ์ƒท 2024-01-26 ์˜ค์ „ 8 36 16

2. How to use ?(Basic)

def index(request):
    return standard_index(request, File, {}, FileCreateForm, 'file', None,
                          generate_crud_filetable,
                          None)

2.1 ์˜ˆ์ƒ ๊ฒฐ๊ณผ๋ฌผ

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2024-01-31 แ„‹แ…ฉแ„’แ…ฎ 6 33 17

2.2 ์ธ์ž ์„ค๋ช…

:param request: HttpRequest ๊ฐ์ฒด
:param model: Django ๋ชจ๋ธ ํด๋ž˜์Šค (์˜ˆ: Project)
:param model_filter: ๋ชจ๋ธ ์ฟผ๋ฆฌ์…‹ ํ•„ํ„ฐ๋ง์„ ์œ„ํ•œ ๋”•์…”๋„ˆ๋ฆฌ
:param form_class: Django ํผ ํด๋ž˜์Šค (์˜ˆ: ProjectCreateForm)
:param url_path: ๋ฌธ์ž์—ด๋กœ ๊ตฌ์„ฑ๋œ URL ๊ฒฝ๋กœ
:param base: ๋ฌธ์ž์—ด๋กœ ๊ตฌ์„ฑ๋œ ๊ธฐ๋ณธ ํ…œํ”Œ๋ฆฟ ๊ฒฝ๋กœ
:param crud_table: CRUD ํ…Œ์ด๋ธ” ์ƒ์„ฑ ํ•จ์ˆ˜
:param callback: ์„ ํƒ์ ์ธ ์ฝœ๋ฐฑ ํ•จ์ˆ˜ (ํ•จ์ˆ˜ ๋˜๋Š” ๋ฉ”์„œ๋“œ)
:param callback_kwargs: ์ฝœ๋ฐฑ ํ•จ์ˆ˜์— ์ „๋‹ฌํ•  ์ถ”๊ฐ€ ํ‚ค์›Œ๋“œ ์ธ์ž๋“ค
:return: HttpResponse ๊ฐ์ฒด

ํ•จ์ˆ˜๋Š” Django ๋ชจ๋ธ์— ๋Œ€ํ•œ ํ‘œ์ค€ ์ธ๋ฑ์Šค ๋ทฐ๋ฅผ ์ƒ์„ฑํ•˜๋ฉฐ CRUD ์ž‘์—…์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

2.3 CRUD Table ์ƒ์„ฑ ํ•˜๊ธฐ

model, model_filter,form_class , curd_table 4๊ฐ€์ง€ ์ธ์ž์™€ **kwargs ์€ CRUD ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

2.3.1 ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ table ์€ helper.generate_crud_table ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

def index(request):
    return standard_index(request, File, {}, FileCreateForm, 'file', None,
                          generate_crud_filetable,
                          None)

2.3.2 ๋กœ์ง

2.3.2.1 ๋กœ์ง ๊ฐœ์š”

helper.generate_crud_table ์€ Model ๋‚ด Form ๋‚ด ์ •์˜๋˜์–ด ์žˆ๋Š” field ์„ table ํ˜•ํƒœ๋กœ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ model_filter ๋‚ด key-value ๊ฐ€ ์ถ”๊ฐ€๋˜์–ด ์žˆ๋‹ค๋ฉด filter ์„ ์ˆ˜ํ–‰ํ•ด ์กฐ๊ฑด์— ๋งž๋Š” ์ •๋ณด๋งŒ์„ ํ…Œ์ด๋ธ”๋กœ ๋งŒ๋“ค์–ด ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ฝ”๋“œ ์ˆ˜์ค€์—์„œ ์ด์•ผ๊ธฐํ•˜์ž๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Model.objects.filter(key=value)

2.3.2.2 CRUD button ์ถ”๊ฐ€ํ•˜๊ธฐ

์œ„์—์„œ ๋งŒ๋“ค์–ด์ง„ ํ…Œ์ด๋ธ”์— create button , detail button , update button , delete button ์ƒ์„ฑํ•ด ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

![์Šคํฌ๋ฆฐ์ƒท 2024-01-31 ์˜คํ›„ 6.43.51](/Users/kimseongjung/Library/Application Support/typora-user-images/์Šคํฌ๋ฆฐ์ƒท 2024-01-31 ์˜คํ›„ 6.43.51.png)

์ธ์ž url_path ์€ crud_table function ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ธ์ž๋กœ์„œ create, deatil, update, delete button ์˜ url ์„ ์ƒ์„ฑํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.(โš ๏ธ์•„๋ž˜ ๊ทธ๋ฆผ์—์„œ Url path ์„ ์ฐธ์กฐํ•ด ์ฃผ์„ธ์š”. )

url_path ์ค‘ create, update, delete, datail ๋ถ€๋ถ„์„ ์ œ์™ธํ•œ url_path ์„ ์ž…๋ ฅํ•˜๋ฉด ๋œ๋‹ค.

๊ฐ button ๋ณ„ url ์€ ์•„๋ž˜์™€ ๊ฐ™์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. Create : {base_url}/{url_path}/create Update : {base_url}/{url_path}/update Delete : {base_url}/{url_path}/delete Detail(Read) : {base_url}/{url_path}/Detail

2.3.3 Custom generate crud table

์‚ฌ์šฉ์ž ๋ชฉ์ ์— ๋งž๊ฒŒ CRUD Table ๋‚ด๋ถ€ ๋กœ์ง์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ• ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ๋“ค์–ด ๊ฐ€๋ น ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์„์ˆ˜ ์žˆ๋Š” ๋งํฌ๋ฅผ ๊ฑด๋‹ค๋˜๊ฐ€ ๋ง์ด์ฃ .

์ด๋•Œ ์‚ฌ์šฉ์ž๋Š” ์ž์‹ ๋งŒ์˜ custom generate crud table ์„ ์ƒ์„ฑ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

def fn(base_url, objects, field_names, url_path, **kwargs):

์‚ฌ์šฉ์ž๋Š” ๋ชฉ์ ์— ๋งž๊ฒŒ ์—ฌ๋Ÿฌ๊ฐœ์˜ table ์„ ๋งŒ๋“ค์–ด ์ ์šฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋ น ๊ฐ€์žฅ๊ธฐ๋ณธ์ ์ธ crud table ์€ ์•„๋ž˜ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

def generate_crud_table(base_url, objects, field_names, url_path, **kwargs):
      field_names = field_names + ['detail', 'update', 'delete']
    if objects:  # ํ…Œ์ด๋ธ” ๋‚ด instance ์กด์žฌ ์‹œ ์•„๋ž˜ ์ฝ”๋“œ ์ˆ˜ํ–‰
        object_df = pd.DataFrame.from_records(objects.values())

        # detail button (read)
        append_onclick_button('detail', base_url, object_df, url_path)

        # generate update urls, (update)
        append_onclick_button('update', base_url, object_df, url_path)

        # delete button (delete)
        append_onclick_button('delete', base_url, object_df, url_path)


    else:  # ํ…Œ์ด๋ธ”์ด ํ•˜๋‚˜๋„ ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด ์•„๋ž˜ ์ฝ”๋“œ ์ˆ˜ํ–‰
        object_df = pd.DataFrame(columns=field_names)

    object_df = object_df.loc[:, field_names]
    # df -> html
    table_html = object_df.to_html(escape=False)

    # create button
    url = generate_url(base_url, os.path.join(url_path, 'create'))
    button_tag = create_button(url, 'create')
    crud_table = button_tag + table_html
    return crud_table

์‚ฌ์šฉ์ž๋Š” ์œ„ ์ฝ”๋“œ๋ฅผ ๋ณ€ํ˜•ํ•˜์—ฌ ๊ฐ์ž์˜ ๋ชฉ์ ์— ๋งž๋Š” crud table ์„ ์ƒ์„ฑํ• ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œ ํ• ์ˆ˜ ์žˆ๋Š” ๋งํฌ๊ฐ€ ๊ฐ™์ด ์žˆ๋Š” table ์„ ์ƒ์„ฑํ•˜๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

def generate_crud_filetable(base_url, objects, field_names, url_path, **kwargs):
    """
    ๋‹ค์šด๋กœ๋“œ ๋งํฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    ์ œ๊ณต๋œ ๊ฐ์ฒด์™€ ํ•„๋“œ ์ด๋ฆ„์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ CRUD ํ…Œ์ด๋ธ”์„ HTML ํ˜•์‹์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    ์ƒ์„ฑ๋  table ๊ฐ€์žฅ ์˜ค๋ฅธ์ชฝ field Detail,  Update , Delete field ์„ ์ƒ์„ฑํ•˜๊ณ  button ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    +----------+
    | create   |
    | <button> |
    +--------+-------+----------+----------+----------+
    | Object | Field | Detail   | Update   | Delete   |
    +--------+-------+----------+----------+----------+
    | Object1| Field1| <button> | <button> | <button> |
    | Object2| Field2| <button> | <button> | <button> |
    +--------+-------+----------+----------+----------+

    """
    target_column = kwargs['target_column'] #<-- ์ถ”๊ฐ€๋œ ์ฝ”๋“œ
    field_names = field_names + ['detail', 'update', 'delete']

    if objects:  # ํ…Œ์ด๋ธ” ๋‚ด instance ์กด์žฌ ์‹œ ์•„๋ž˜ ์ฝ”๋“œ ์ˆ˜ํ–‰

        # ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ๋ฅผ ์œ„ํ•œ URL ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ
        urls = [file.filecontent.url for file in objects] #<-- ์ถ”๊ฐ€๋œ ์ฝ”๋“œ
        # filecontent column ์— ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ ๋งํฌ ์ƒ์„ฑ 
        object_df = pd.DataFrame.from_records(objects.values()) #<-- ์ถ”๊ฐ€๋œ ์ฝ”๋“œ
        target_series = object_df.loc[:, target_colname]#<-- ์ถ”๊ฐ€๋œ ์ฝ”๋“œ
        url_tags = [wrap_with_tag(str(ele), tag_name='a', href=url) for ele, url in zip(target_series, urls)]#<-- ์ถ”๊ฐ€๋œ ์ฝ”๋“œ
        object_df.loc[:, target_colname] = url_tags#<-- ์ถ”๊ฐ€๋œ ์ฝ”๋“œ

        # detail button (read)
        append_onclick_button('detail', base_url, object_df, url_path)

        # generate update urls, (update)
        append_onclick_button('update', base_url, object_df, url_path)

        # delete button (delete)
        append_onclick_button('delete', base_url, object_df, url_path)


    else:  # ํ…Œ์ด๋ธ”์ด ํ•˜๋‚˜๋„ ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด ์•„๋ž˜ ์ฝ”๋“œ ์ˆ˜ํ–‰
        object_df = pd.DataFrame(columns=field_names)

    object_df = object_df.loc[:, field_names]
    # df -> html
    table_html = object_df.to_html(escape=False)

    # create button
    url = generate_url(base_url, os.path.join(url_path, 'create'))
    button_tag = create_button(url, 'create')
    crud_table = button_tag + table_html
    return crud_table

ํ•˜์ง€๋งŒ ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ ๋งํฌ๊ฐ€ ์žˆ๋Š” crud table ์€ ์•„๋ž˜ table ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.#<-- ์ถ”๊ฐ€๋œ ์ฝ”๋“œ์„ ํ™•์ธํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. โš ๏ธ ํ‚ค์›Œ๋“œ ์ธ์ž๊ฐ€ ๊ณตํ†ต์ ์œผ๋กœ generate crud table ์—์„œ๋„ ์‚ฌ์šฉ๋˜๋Š”๊ฒƒ์— ์ฃผ์˜ํ•ด ์ฃผ์„ธ์š”.

2.4 Callback function

์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด callback function ์„ ํ†ตํ•ด์„œ ์šฐ๋ฆฌ๋Š” ๋‹ค์–‘ํ•œ ์ž‘์—…๋“ค์„ ์ˆ˜ํ–‰ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น function ์—์„œ์˜ callback function ์€ ๋”ฑํžˆ ์ •ํ•ด์ง„ ๋ชฉ์ ์€ ์—†์ง€๋งŒ ๋Œ€ํ‘œ์ ์œผ๋กœ 2๊ฐ€์ง€ ๋ชฉ์ ์„ ๊ฐ€์ง€๊ณ  ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  1. content design ์„ ์ž…ํžˆ๊ฑฐ๋‚˜ html ์„ ์ถ”๊ฐ€ํ•˜๋Š” ์ž‘์—…๋“ค์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    1. ์ œ๋ชฉ ์„ ์ถ”๊ฐ€ํ•˜๋Š” ์ž‘์—…๋“ค์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

      title = h_tag(2, 'ํ”„๋กœ์ ํŠธ ๋ชฉ๋ก')
    2. ์œ„ ์˜ˆ์ œ์—์„œ๋Š” curd_table_html ์— div class=card ์— curd_table_html ์„ ์‚ฝ์ž…ํ•˜๋Š” ์ž‘์—…๋“ค์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

      added_contents = kwargs['added_contents']
      added_contents[0] = title + card_row((added_contents[0], 12)

โš ๏ธ ์ถ”๊ฐ€์ ์œผ๋กœ added_contents ์— ์ถ”๊ฐ€๋œ ์ž๋ฃŒ๋Š” ์ˆœ์„œ๋Œ€๋กœ ํ™”๋ฉด์— ๋žœ๋”๋ง ๋ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž๋Š” ํ‚ค์›Œ๋“œ ์ธ์ž๋ฅผ ํ†ตํ•ด ๋ณด๋‹ค ์ž์œ ๋กญ๊ฒŒ ์ž‘์—…๋“ค์„ ์ˆ˜ํ–‰ ํ• ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. โš ๏ธ ํ‚ค์›Œ๋“œ ์ธ์ž๊ฐ€ ๊ณตํ†ต์ ์œผ๋กœ generate crud table ์—์„œ๋„ ์‚ฌ์šฉ๋˜๋Š”๊ฒƒ์— ์ฃผ์˜ํ•ด ์ฃผ์„ธ์š”.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ