file management system - pai-plznw4me/django-initializer GitHub Wiki

File Management system (vanilla)

퍼블릭에이아이 ν‘œμ€€ 파일 관리 μ‹œμŠ€ν…œ ν•΄λ‹Ή μ‹œμŠ€ν…œμ„ 기반으둜 μ—¬λŸ¬ κΈ°λŠ₯을 μΆ”κ°€ ν•  수 μžˆλ‹€.
λ‹€λ₯Έ μ‹œμŠ€ν…œκ³Ό 연동이 κ°€λŠ₯ν•˜λ‹€.
ν˜„μž¬ λ¬Έμ„œμ—μ„œ λ‹€λ£¨λŠ” 버전은 Vanilla 버전이닀.

  • Ohter version
    • File Management system (with ams)
    • File Management system (with ams, project)

λ¬Έμ„œ λͺ©μ  및 λŒ€μƒ λ…μž

λŒ€μƒ λ…μž : 개발자
λ¬Έμ„œ λͺ©μ  : ν•΄λ‹Ή λ¬Έμ„œμ˜ λͺ©μ μ€ 파일 관리 μ‹œμŠ€ν…œμ˜ κΈ°λŠ₯을 μ²˜μŒλΆ€ν„° κ΅¬ν˜„ν•΄ λ³Έλ‹€.
이λ₯Ό 톡해 κ°œλ°œμžλŠ” 파일 관리 μ‹œμŠ€ν…œμ˜ ꡬ쑰λ₯Ό μ΄ν•΄ν•˜κ³ 
μΆ”κ°€ κΈ°λŠ₯ ν™•μž₯ 및 λ‹€λ₯Έ μ‹œμŠ€ν…œκ³Όμ˜ 연동 ν• μˆ˜ μžˆλŠ” λŠ₯λ ₯을 λ°°μ–‘ν•œλ‹€.

FMS νŠΉμ§•

  • 쀑볡 파일 μ—…λ‘œλ“œ κ°€λŠ₯
  • 파일 μ—…λ‘œλ“œ κΈ°λŠ₯ / 파일 λ‹€μš΄λ‘œλ“œ κΈ°λŠ₯
  • 파일 관리λ₯Ό μœ„ν•΄ ν•„μš”ν•œ 메타 정보 μΆ”μΆœ 및 μ €μž₯
  • 닀쀑 κΆŒν•œ, κΆŒν•œ 여뢀에 λ”°λ₯Έ λ‹€μš΄λ‘œλ“œ κΈ°λŠ₯(account management system 연동 ν•„μš”)
  • CRUD κ΅¬ν˜„
intro

0. λ“€μ–΄κ°€κΈ° 전에

  1. Project 생성 ( ν•΄λ‹Ή ν¬μŠ€νŒ…μ—μ„œλŠ” fms )
  2. app 생성( ν•΄λ‹Ή ν¬μŠ€νŒ…μ—μ„œλŠ” file)
  3. project URLConf 에 app url 등둝
  4. package install

1. Create

1.1 Model 생성 및 migration

  • Model - Form -Template- View νŒ¨ν„΄μœΌλ‘œ 개발 됨.

1.1.1 Model

from django.db import models

from file.validators import validate_version_format

# Create your models here.
class File(models.Model):
    # file content
    filecontent = models.FileField()
    # 파일 이름
    name = models.CharField(max_length=100)
    # 파일 μ„€λͺ…
    desc = models.TextField(null=True, blank=True)
    # 파일 ν™•μž₯자
    ext = models.CharField(max_length=10, null=True)
    # 파일 μš©λŸ‰
    size = models.IntegerField()
    # λ¬Έμ„œ μ—…λ‘œλ“œ μ‹œκ°„
    upload_datetime = models.DateTimeField(auto_now_add=True)
    # λ¬Έμ„œ 생성 μ‹œκ°„, creation_date λŠ” λ¬Έμ„œλ₯Ό μ‹€μ œ μƒμ„±ν•œ μ‹œκ°„
    creation_date = models.DateField(null=True, blank=True)
    # λ¬Έμ„œ 버전
    version = models.CharField(max_length=100, validators=[validate_version_format], null=True, blank=True)
  • validator 개발 : λͺ¨λΈ μˆ˜μ€€μ—μ„œμ˜ μœ νš¨μ„±μ„ κ²€μ¦ν•œλ‹€
# file/validators.py
import re
from django.core.exceptions import ValidationError

def validate_version_format(value):
    # "v.x.x.x"와 같은 ν˜•μ‹μΈμ§€ 검사
    pattern = re.compile(r'^v\.\d+\.\d+\.\d+$')
    if not pattern.match(value):
        raise ValidationError('Invalid version format. Use "v.x.x.x" format.')

1.1.2 Migration

python manage.py makemigrations
python manage.py migrates

1.1.3 Form 생성

# fms/file/forms.py
from django import forms
from .models import File

class FileCreationForm(forms.ModelForm):
    class Meta:
        model = File
        fields = ['filecontent',
                  'desc',
                  'creation_date',
                  'version']

        widgets = {
            'creation_date': forms.widgets.DateInput(attrs={'type': 'date'})
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

1.1.4 View

# Create your views here.
def create(request):
    if request.method == 'POST':
        form = FileCreationForm(request.POST, request.FILES)  # <-- FILES 와 같이 μž…λ ₯이 λ˜μ–΄μ•Ό ν•œλ‹€.
        if form.is_valid():
            inst = form.save(commit=False)
            # 파일 속성 μΆ”μΆœ 및 생성
            file = form.cleaned_data['filecontent']
            file_ext = os.path.splitext(file.name)[1]

            # 속성 정보 μ €μž₯
            inst.name = file.name
            inst.size = file.size
            inst.ext = file_ext
            inst = form.save(commit=False)

            # file field 파일 μ €μž₯
            inst.filecontent.save(file.name, file)

            # 일반 form data μ €μž₯
            inst.save()
            return redirect(to='file:index')
        else:

            print('Errors:', form.errors)
            return render(request, template_name='file/create.html', context={'form': form, 'errors': form.errors})

    elif request.method == 'GET':
        form = FileCreationForm()  # <-- FILES 와 같이 μž…λ ₯이 λ˜μ–΄μ•Ό ν•œλ‹€.
        return render(request, template_name='file/create.html', context={'form': form})

    else:
        raise NotImplementedError
    return HttpResponse('200')

1.1.5 HTML Templates

<h2>File System</h2>
<form action="" method="post" enctype="multipart/form-data">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">전솑</button>
</form>

1.1.6 URLConf

# fms/file/urls.py
from django.urls import path
from file.views import index, create

app_name='file'
urlpatterns = [
    path('create/', create, name='create'),
]

2. Read

2.2.4 View

  • HTML 생성 μ½”λ“œλ₯Ό 였직 Python 을 ν™œμš©ν•˜μ—¬ 생산 ν•©λ‹ˆλ‹€. λ”°λ‘œ HTML template κ°€ ν•„μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • 이 μ½”λ“œμ˜ 핡심은 ❗️DB을 DataFrame 으둜 λ³€κ²½ ν•œ ν›„ DataFrame ν˜•νƒœμ—μ„œ ν…Œμ΄λΈ” μ „μ²˜λ¦¬λ₯Ό μˆ˜ν–‰ν•˜λŠ” 것 μž…λ‹ˆλ‹€.
    • Cell λ‚΄ <a> tag μΆ”κ°€
    • datetime field 포맷을 DataFrame μ—μ„œ μ œμ–΄ν•©λ‹ˆλ‹€.
def index(request):
	 # λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ λͺ¨λ“  File 객체λ₯Ό κ°€μ Έμ˜΄
    files = File.objects.all()

    # λ°μ΄ν„°λ² μ΄μŠ€λ‘œλΆ€ν„° DataFrame 생성
    files_df = pd.DataFrame.from_records(files.values())

    # ν•„μš”ν•œ column μˆœμ„œλ‘œ DataFrame 열을 선택
    column_order = ['id', 'name', 'filecontent', 'desc', 'ext', 'size', 'upload_datetime', 'creation_date',
                    'version']
    files_df = files_df.loc[:, column_order]

    # 파일 λ‹€μš΄λ‘œλ“œλ₯Ό μœ„ν•œ URL 리슀트 생성
    urls = [file.filecontent.url for file in files]

    # 파일 이름을 ν΄λ¦­ν•˜λ©΄ ν•΄λ‹Ή νŒŒμΌμ„ λ‹€μš΄λ‘œλ“œν•  수 μžˆλŠ” 링크둜 λ³€ν™˜
    target_colname = 'name'
    target_series = files_df.loc[:, target_colname]
    url_tags = [wrap_with_tag(str(ele), tag_name='a', href=url) for ele, url in zip(target_series, urls)]
    files_df.loc[:, target_colname] = url_tags

    # μ—…λ‘œλ“œ μ‹œκ°„μ„ μ›ν•˜λŠ” ν˜•μ‹μœΌλ‘œ λ³€ν™˜
    target_colname = 'upload_datetime'
    files_df[target_colname] = files_df[target_colname].dt.strftime('%y:%m:%d %H:%M:%S')

    # DataFrame을 HTML둜 λ³€ν™˜
    table_html = files_df.to_html(escape=False)

    # HTML ν…œν”Œλ¦Ώ 파일의 μ ˆλŒ€ 경둜 κ°€μ Έμ˜€κΈ°
    abspath = get_template_path('file/bootstrap.html')  # {app_name}/{templates 이름}을 μž…λ ₯ν•˜λ©΄ μ ˆλŒ€ 경둜둜 λ°˜ν™˜
    # BeautifulSoup둜 HTML ν…œν”Œλ¦Ώ νŒŒμΌμ„ μ½μ–΄μ˜€κΈ°
    base_soup = bs4_load(abspath)

    # ν…œν”Œλ¦Ώμ— DataFrame을 μ‚½μž…
    soup = insert_html_to_body(soup=base_soup, target=table_html)

    # BeautifulSoup 객체λ₯Ό HttpResponse둜 λ°˜ν™˜
    return HttpResponse(soup.prettify(formatter=None))
⚠️ **GitHub.com Fallback** ⚠️