2017-04-25 19 views
0

는 : 내가 볼Django 1.10+에서 송장 계산을위한 "Best Practice"는 무엇입니까? 하나는 두 가지 모델이있는 경우

class Invoice(models.Model): 
    class Meta: 
     ordering = ('-date_added',) 

    number = models.CharField(max_length=10,) 
    comments = models.TextField(blank=True, help_text="Notes about this invoice.") 
    total = models.DecimalField(max_digits=9, decimal_places=2, default="0") 
    date_added = models.DateTimeField(_('date added'), auto_now_add=True) 
    date_modified = models.DateTimeField(_('date modified'), auto_now=True) 

def __unicode__(self): 
    return "%s: total %s" % (self.number, self.total) 

class Part(models.Model): 
    for_invoice = models.ForeignKey(Invoice) 
    description = models.CharField(max_length=200, blank=True, help_text=_("Briefly describe the part.")) 
    supplier = models.CharField(max_length=100, blank=True, help_text=_("Supplier Name.")) 
    supplier_number = models.CharField(max_length=100, blank=False, help_text=_("Supplier's order number.")) 
    qty = models.DecimalField(max_digits=3, decimal_places=0, blank=False, null=False, help_text=_("How many are needed?")) 
    cost = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True, help_text=_("Price paid per unit")) 
    line_total = models.DecimalField(max_digits=9, decimal_places=2, default="0") 
    date_added = models.DateTimeField(auto_now_add=True) 
    date_modified = models.DateTimeField(auto_now=True) 

def __unicode__(self): 
    return "%s: total %s" % (self.for_invoice, self.line_total) 

첫 번째 선택은 하나가 계산 된 모델 필드로 "line_total"또는 "전체"를 구현할 수있다. 그러나 그렇게하면 변경 목록을 "line_total"또는 "total"로 정렬 할 수 없으며 사용자는이를 수행 할 수 있기를 원합니다. 그래서 저는 모델에 저장된 필드를 만들었습니다. 나는 코드가 "전체"와 "line_total"필드를 계산하고 업데이트 할 정의 할 수 있습니다 4 곳을 볼 장고 1.10 문서를 읽기

:

  1. ModelAdmin.save_model (요청, OBJ, 양식, 변경) 및 ModelAdmin.save_formset (요청 형태의 formset 변경)
  2. ModelAdmin.save_related (요청 폼 formsets 변경)
  3. model.save (자기, 인수 *, ** kwargs로))에 저장
  4. 신호

저장 신호가 너무 낮아 단일 모델 저장 이벤트에 묶여 있으며 요청이나 세션에 액세스 할 수없는 것으로 보입니다. 따라서 "Part"기록을 모두 모으는 것은 "성가신"일 것입니다.

마찬가지로 model.save 메서드도 너무 세분화 된 것 같습니다. Invoice.save 메소드를 사용할 수 있다면 Invoice.part_set.all()을 통해 모든 관련 부분에 쉽게 액세스 할 수 있기 때문에 "편리"할 것입니다.이 쿼리 세트를 반복하면 line_total을 손쉽게 업데이트 한 다음 main 합계. 그러나이 시점에서 모든 새로운/변경된 부품 레코드가 다시 저장됩니까? 그리고 HttpRequest에 액세스 할 수 없습니다.

관리자의 save_model에도 동일하게 적용됩니다. 그러나 막연한 기억으로 관련 부품을 먼저 저장할 수 있습니다. Admin의 인보이스 추가/편집 페이지에서 인라인을 사용하여 부품을 나열합니다.

방금 ​​ModelAdmin.save_related에 추가되었습니다. 나는 그 것을 잊었다. 주 송장은이 시점에서 저장되므로 어쩌면 이것이 모든 부품 레코드를 업데이트하고 부모 총계를 업데이트하는 가장 좋은 장소 일 수 있습니까?

미리 감사드립니다.

+2

계산 된 필드별로 정렬 할 수 있습니다. [이 답변] (http://stackoverflow.com/a/42660093/113962)을 참조하십시오. – Alasdair

답변

0

덕분에 Alasdair 님의 제안이지만,이 클라이언트는 완벽한 맞춤 솔루션을 원하지 않습니다. 그래서 나는 관리자 개조를 고수하고있다.

옵션 2를 사용하여 테스트하고 있습니다. save_related Admin의 기능입니다. 아래 코드 :

from decimal import Decimal 

    def save_related(self, request, form, formsets, change): 
    total = Decimal('0.00') 
    for myform in formsets: 
     for mf in myform.forms: 
     # Skip empty rows (if any): 
     if len(mf.cleaned_data) > 0: 
      # Update item line total from item quantity and price: 
      mf.instance.line_total = mf.instance.qty * mf.instance.cost 
      # Add line item total to grand total: 
      total += mf.instance.line_total 
      # re-save line item: 
      mf.instance.save() 
    # Update grand total on the invoice: 
    form.instance.total = total 
    # re-save the invoice record: 
    form.instance.save() 
    # Chain to inherited code: 
    super(InvoiceAdmin, self).save_related(request, form, formsets, change) 

불쌍한 변수 이름은 죄송합니다. 나는 인라인 형태가 2 단계로 깊게 잡혀 있었기 때문에 경계로부터 벗어났다. 첫 번째 레이어는 formets 그룹 (하나만)이고 첫 번째 formset은 내 양식입니다. 모든 것은 .instance 개체이며, 나는 그들이 이미 저장되었다고 생각합니다. 이 기능의 기본 동작은 기본 서식이 이미 저장되어있는 양식 세트를 저장하는 것입니다.

어쨌든 작동하므로 문서를 오해 한 것으로 간주합니다.