취미삼아 배우는 프로그래밍

Django로 개인 업무(ERP) 홈페이지 만들기-4 본문

파이썬(장고)

Django로 개인 업무(ERP) 홈페이지 만들기-4

Nadure 2020. 11. 13. 03:53

자 이제 어떻게 보면 가장 중요하고 가장 많이 쓰일 메뉴를 만들 차례다.

그래서 지금의 글은 그 구상에 관한 글이다.

 

구상

 여러 장고 앱들을 날려먹으면서 느낀 경험상 세부 리스트(Detailed List)를 작성하는건 가장 마지막 과정이 된다.  작은 모델들을 컨트롤해 차곡차곡 쌓아다가 거대한 짐덩어리들을 만들어야 하기 때문이다. 또한 여기서 코드를 잘못 놀리면 퍼포먼스 문제가 생길 확률이 가장 높다.

 일단 엑셀형식으로 테이블을 짜봤다. 내가 원하는 형태는 결국 테이블 형태로 출력되고 이를 확인하는것이기 때문이다.

요런 형태의 테이블이 목표다.

 

1. 테이블 만들기

 장고를 할 때 django_tables2 모듈이 가장 편한것 같다. django-tables2.readthedocs.io/en/latest/

 

django-tables2 - An app for creating HTML tables — django-tables2 2.3.1 documentation

© Copyright Revision 21b8935d.

django-tables2.readthedocs.io

import django_tables2 as tables

data = [
    {"name": "Bradley"},
    {"name": "Stevie"},
]

class NameTable(tables.Table):
    name = tables.Column()

 

 이와 같은 형태가 가장 기초적인 테이블 사용법인데, 내 모델들은 데이터가 모두 쪼개져 있기 때문에 위처럼 데이터를 리스트 형식으로 넣어다가 테이블을 뽑아내는 형태로 하려한다.

 일단은 구상만 하는거니까, 대략적으로 가닥만 잡아놓는다.

 

2. 랭킹 구현에 대해서

 어떻게 랭킹을 표현할까 생각을 조금 해봤다. 순번에 관한 필드를 하나 더 추가하고, 이 값은 초기엔 id값으로 준다. 결국 이 rank_number is_completed라는 필드를 통해서 순번을 컨트롤 해야할 듯 싶다.

class IntegratedInfo(models.Model):
    base_data = models.ForeignKey(LocationData, on_delete=models.CASCADE, null=True, blank=True)
    items = models.ManyToManyField(ItemInfo)
    is_completed = models.BooleanField(default=False, verbose_name="완료")
    is_order_printed = models.BooleanField(default=False, verbose_name="오더인쇄함")
    connected_file = models.ForeignKey(UploadedFiles, on_delete=models.CASCADE, blank=True, null=True)
    filar_maded = models.CharField(max_length=15, default=None, null=True, blank=True)
    rank_number = models.IntegerField(verbose_name="순번", default=0, null=True, blank=True)
    # pdf 페이지 정보도 넣어야할듯 > 
    # 오더파일 생성시
    # 파일 경로를 바꿔주는것도 추가 필요.
    
    def __str__(self):
        return str(self.base_data)
    
    def rank_init(self, *args, **kwargs):
        self.rank_number = self.id
        self.save()

 

그림으로 대충 표현하자면

 근데 rank_number 값들 사이에서 빈 값이 하나 띄우고 생기게 된다면(is_completed=False로 filter를 할 것이니 중간에 빌 수 밖에 없다.) 곤란해진다. 그렇기 때문에 rank_number 값이 초기에 id값이기 때문에 결국 rank_number 최대값~ 최소값 사이에서의 랭크 재정렬이 일어나야 한다.

 

그래 이론으로 짠 알고리즘상 그렇다 치자.

 그럼, 프론트단에서 보내야하는 재정렬 하는 함수의 입력값은 어떻게 처리해야할까? ㅡ 결과값을 위해서 무슨 값을 넣어야 할까?

  • 순서가 바뀌어진 모든 데이터들의 id값을 순서대로 넘긴다.
  • 어쨋든 처음에 뷰단에 보여진 rank_number들의 값은 순서대로 돼있다. 그렇기에 바뀌어진 rank_number 값을 순서대로 넘기고 이를 순서대로 처리한다. 이 때는 rank_number를 id값에 대해서 대체하여 바꾸어야 한다.
  • 둘 다 섞는다. {"id":"rank_number", "id":"rank_number"} 형태의 JsonString을 둘 다 넣어서 보내고 이를 개별적으로 처리토록 한다. 로직은 가장 심플하지만, 처리하는 데이터가 많아지면 save마다 커밋이 날라가므로 상당히 퍼포먼스 문제가 있을 것 같다.(400개의 순서를 바꾸는거면, 400번의 저장이 이뤄질 수도 있음.) filter로 일괄 값 수정하는것도 있었던거 같은데 찾아봐야겠다.

 

3. 결국엔 테스트 코드(셋 다 짜야함)

테스트 코드 작성방안

  1. 우선 50개 정도 더미데이터를 만든다.
  2. 무작위로 10 개 정도 is_completed 를 True로 바꾼다.
  3. is_completed=False 인 것으로 filter 하고 rank_number 순서대로 땡겨온다.
  4. 각 함수 모델에 입력하고 결과값을 받아다 결과값과 작동시간을 비교한다.
  5. 더미데이터 갯수를 400개 정도 까지 확대해본다.

 

정도가 되겠다. 일단 한 번 해보고 정리해봐야겠다.

 

ㅡㅡㅡ덧

1안.

stackoverflow.com/questions/3652334/django-queryset-update-field-increasing-descreasing-its-current-value

 

Django queryset update field increasing/descreasing its current value

I am trying to change order of nodes in my tree. Everything works fine, but I would like to know if there is some beautiful, easy way of updating multiple fields by increasing its actual value by 1...

stackoverflow.com

 

아..? F함수를 써서 일괄 rank_nubmer를 수정하면 퍼포먼스에 상당히 도움될 것 같다. 일단 킵

 

2안.

tomforb.es/using-bulk-update-in-django-2.2/

 

Using bulk update in Django 2.2

My work on adding bulk_update() to Django has been merged and will be released in Django 2.2! Like my filtered aggregates feature it relies heavily on the wonderfully versatile CASE statement to achieve some pretty good speedups for certain use-cases. The

tomforb.es

맞다.. 벌크 업데이트가 있었다.

 

Comments