2

웹 페이지를 구성하려고하는데 현재 웹 응용 프로그램에 각 사용자에 대한 결과 페이지를 넣는 데 어려움이 있습니다. 함께. 그러나 그것은 감각이 내 머리를 만들어 내 모델 관계가 이상적인 경우Django - 여러 외래 키 관계가있는 모델로 데이터베이스 쿼리를 최적화하면서 결과 정보 표시

class Fault(models.Model): 
    name = models.CharField(max_length=255) 
    severity = models.PositiveSmallIntegerField(default=0) 
    description = models.CharField(max_length=1024, null=False, blank=False) 
    recommendation = models.CharField(max_length=1024, null=False, blank=False) 
    date_added = models.DateTimeField(_('date added'), default=timezone.now) 
    ... 


class FaultInstance(models.Model): 
    auto = models.ForeignKey(Auto) 
    fault = models.ForeignKey(Fault) 
    date_added = models.DateTimeField(_('date added'), default=timezone.now) 

    objects = FaultInstanceManager() 
    ... 

class Auto(models.Model): 
    label = models.CharField(max_length=255) 
    model = models.CharField(max_length=255) 
    make = models.CharField(max_length=255) 
    year = models.IntegerField(max_length=4) 
    user = models.ForeignKey(AUTH_USER_MODEL) 
    ... 

나도 몰라 : 여기

내 모델 모양을합니다. 따라서 각 사용자는 복수 자동 개체를 가질 수 있습니다. 그리고 각 자동은 복수 FaultInstance 개체를 가질 수 있습니다. 사용자가 자신의 자동차에 걸쳐 가지고 결과 페이지에서

, 나는 모든 FaultInstances을 나열합니다. 그리고 각 열거 된 FaultInstance 아래에는 정보가있는 결함이있는 모든 자동차 목록이 있습니다 (여기에 제가 생각한 것입니다).

FaultInstance: 
    FaultDescription: 
    FaultRecommendation: 
    ListofAutosWithFault: 
     AutoLabel AutoModel AutoYear ... 
     AutoLabel AutoModel AutoYear ... 

분명히 심각도 (낮은 숫자에 많은 수의) 발주

모든 FaultInstance 목록, 것들을 나는의 목록 작성의 많은 작업을 수행 할 것을 의미하는 올바른 방법을 파이썬/Django 측면의 일을하고 어떤 논리 또는 템플릿에서 처리를 피하십시오. 난 단지 5 개 심각도 수준이있는 경우, 나는 각각에 대한 목록을 만들 수 있습니다

class FaultInstanceManager(models.Manager): 
    def get_faults_by_user_severity(self, user, severity): 
     faults = defaultdict(list) 
     qs_faultinst = self.model.objects.select_related().filter(
       auto__user=user, fault__severity=severity 
      ).order_by('auto__make') 
     for result in qs_faultinst: 
      faults[result.fault].append(result) 

     faults.default_factory = None 
     return faults 

는 여전히 각 심각도를 지정해야하지만, 그런 것 같아요 : 여기에서 볼 수 있듯이 나는 모델 매니저와 심각도에 따라 목록을 만들 수 있어요 심각도 수준을 지정하고 각 개별 템플릿을 템플릿에 전달합니다. 이것에 대한 제안은 감사하겠습니다. 그러나, 그건 내 문제가 아니야. 내가 지금 당장 멈출 수있는 점은 보고서 맨 위에 요약 테이블을 작성하여 사용자가 모델 | 연도별로 오류 인스턴스를 분류 할 수 있다는 것입니다. 템플릿에 전달할 적절한 쿼리 또는 데이터 구조를 생각할 수 없습니다.

요약 (모든 FaultInstances의 테이블에 다음과 같은 열 헤더와) : 이것은 내가 아래의 예 (메이크업이나 모델 또는 년 동안 통계를 알려드립니다

FaultInstance Make|Model|Year NumberOfAutosAffected 

, 모델에 기초한 분리 결함). 내가 목록에 나열되어 있기 때문에 FaultInstances 내가 오류가에 연결되어 있기 때문에 사용자에게 연결되어 있습니다.

를 들어
Bad Starter  Nissan  1 
Bad Tailight Honda  2 
Bad Tailight Nissan  1 

는 그리고 나는 데이터베이스 쿼리를 최적화하는 동시에이 작업을 수행 할 수와 같은 완벽 주의자입니다. 템플릿에서 쉽게 파싱 될 원래 쿼리에서 데이터 구조를 만들 수 있고 내 보고서 (아마도 defaultdict (목록)의 defaultdict)에서이 두 섹션을 모두 가져올 수 있다면 원하는 작업을 수행 할 수 있습니다. 도움을 주셔서 감사합니다. 잘하면 내 질문은 철저하고 의미가 있습니다.

답변

2

관련 이름을으로 지정하면 쿼리가 간단 해 지므로 의미가 있습니다. 이처럼 :이 경우

class FaultInstance(models.Model): 
    auto = models.ForeignKey(Auto, related_name='fault_instances') 
    fault = models.ForeignKey(Fault, related_name='fault_instances') 
    ... 

class Auto(models.Model): 
    user = models.ForeignKey(AUTH_USER_MODEL, related_name='autos') 

당신이 사용할 수 있습니다

qs_faultinst = user.fault_instances.filter(fault__severity=severity).order_by('auto__make') 

대신을 :

qs_faultinst = self.model.objects.select_related().filter(
       auto__user=user, fault__severity=severity 
      ).order_by('auto__make') 

나는 당신의 요약 테이블을 알아낼 수 없습니다, 할 수있다 당신은 의미 :

Fault Make|Model|Year NumberOfAutosAffected 

이 경우을 사용할 수 있습니다.. 그러나 충분한 데이터가 있다면 It (그룹화)은 여전히 ​​느려질 것입니다. 하나의 쉬운 솔루션은 추가 모델을 만들어 데이터를 비정규 화하는 것입니다. 업데이트하려면 signals을 만들거나 캐시를 사용할 수 없습니다. 당신이 심각도의 미리 정의 된 설정이있는 경우

다음이 생각 : 템플릿에서

class Fault(models.Model): 

    SEVERITY_LOW = 0 
    SEVERITY_MIDDLE = 1 
    SEVERITY_HIGH = 2 
    ... 
    SEVERITY_CHOICES = (
     (SEVERITY_LOW, 'Low'), 
     (SEVERITY_MIDDLE, 'Middle'), 
     (SEVERITY_HIGH, 'High'), 
     ... 
    ) 
    ... 
    severity = models.PositiveSmallIntegerField(default=SEVERITY_LOW, 
               choices=SEVERITY_CHOICES) 
    ... 

을 그냥 Fault.SEVERITY_CHOICES을 반복 할 수 있습니다.

업데이트 :

모델을 변경

:

별도의 모델로

Аllocate 모델 :

class AutoModel(models.Model): 
    name = models.CharField(max_length=255) 

변경 모델 자동차 분야 모델 :

class Auto(models.Model): 
    ... 
    auto_model = models.ForeignKey(AutoModel, related_name='cars') 
    ... 

추가 모델 :

class MyDenormalizedModelForReport(models.Model): 

    fault = models.ForeignKey(Fault, related_name='reports') 
    auto_model = models.ForeignKey(AutoModel, related_name='reports') 
    year = models.IntegerField(max_length=4) 
    number_of_auto_affected = models.IntegerField(default=0) 

에게 신호를 추가 :

def update_denormalized_model(sender, instance, created, **kwargs): 
    if created: 
     rep, dummy_created = MyDenormalizedModelForReport.objects.get_or_create(fault=instance.fault, auto_model=instance.auto.auto_model, year=instance.auto.year) 
     rep.number_of_auto_affected += 1 
     rep.save() 

post_save.connect(update_denormalized_model, sender=FaultInstance) 
+0

나는 내 요약 테이블에 대해 좀 더 정보를 추가했습니다. 내 심각성에 대한 당신의 제안을 좋아합니다. 그러나 데이터를 비정규 화하고 신호를 사용하는 것에 대한 귀하의 제안을 이해하지 못합니다. 더 나은 예를 들어 주시겠습니까? – BoogeyMarquez

+0

내 게시물을 업데이트했습니다. –

+0

자세한 설명은 Andrey에게 감사드립니다. 당신의 답을 옳은 것으로 표시하고 다시 한 번 감사드립니다! – BoogeyMarquez