、私はあなたがやりたいだろう、単一のクエリセットを書き込もうとしましたが、それはあなたのデータモデルに基づいて可能ていないようです。
あなたのデータモデルは、特定の患者が特定の患者を治療した日付範囲を実際には説明していません。あなたが書いているクエリは、あなたがどのようにクエリを書くかにかかわらず、間違った結果を返すでしょう。あなたが現在言っているのは、次のとおりです。
"患者が死亡した場合、この患者を治療した医師はis_main=True
であり、責任を負うとマークされます。" (責任はここに正しい言葉ではないかもしれませんが、あなたはその考えを得るべきです)。
特定の患者に単一のGPをis_main
というように割り当てても、上記のことはうまくいきますが、あなたのデータモデルはこれを強制しないため、エラーが発生する可能性があります。特に、患者が死亡した後にis_main
が変化した場合。私は、次のいずれかのデータモデルを構築します:
class GP(models.Model):
name = models.CharField(max_length=64)
class Patient(models.Model):
name = models.CharField(max_length=64)
class Death(models.Model):
current_gp = models.ForeignKey(GP)
patient = models.ForeignKey(Patient)
date = models.DateField()
class Consultation(models.Model):
gp = models.ForeignKey(GP)
patient = models.ForeignKey(Patient)
start_date = models.DateField()
end_date = models.DateField(blank=True, null=True)
それとも...
class GP(models.Model):
name = models.CharField(max_length=64)
class Patient(models.Model):
name = models.CharField(max_length=64)
class Death(models.Model):
patient = models.ForeignKey(Patient)
date = models.DateField()
class Consultation(models.Model):
gp = models.ForeignKey(GP)
patient = models.ForeignKey(Patient)
start_date = models.DateField()
end_date = models.DateField(blank=True, null=True)
最初の構造はのコストで、非常にパフォーマンスになり、本当に素敵なクエリを可能にする利点を持っています患者の死亡時に追加情報を入力する必要があります。ただし、Consultation
(以前のPatientGPLink)モデルには、この情報を推測するために必要なすべての情報が含まれています。また、Death.current_gpをManyToManyFieldにして、複数のGPが患者の責任を担うようにすることもできます。
2番目の構造は同じ情報を収集できますが、別のテーブルを結合するdatetimeフィルタリングを必要とし、クエリをより遅く複雑にします。
これは、データが正しいという点で、そのis_main
フィールドの管理を非常に意識している場合、これは少し関係がありません。しかし、私はあなたのビューから(おそらく)より効率的な方法で、必要な情報を照会する方法をお見せしましょう:
:
その後
def my_view(request):
doctors = GP.objects.all()
periods = get_time_periods() # however it is you do this...
smallest_date = get_smallest_date(time_periods)
largest_date = get_largest_date(time_periods)
deaths = Death.objects.select_related(depth=1).filter(date__range=(smallest_date, largest_date))
# build the results table with initial count of 0 to account for all doctors
# {period: {doctor: count}}
results = dict((period,{doctor: 0}) for doctor in doctors for period in periods)
for death in deaths:
for period in time_periods: # I'm assuming this is a small range of values
if death.date > period['start_date'] and death.date < period['end_date']:
results[period][death.current_gp] += 1 # add a death to the count
、あなたのテンプレートで、あなたはすべて事前に計算情報をresults
テーブルを持っています
<table>
{% for period, lookup in results.items %}
{% for doctor, deaths in lookup.items %}
<tr>
<td>{{ period }}</td>
<td>{{ doctor }}</td>
<td>{{ deaths }}</td>
</tr>
{% endfor %}
{% endfor %}
</table>
合計2つのSQLクエリがあります。このように多くの手動処理がありますが、結果を計算するのは、現在実行しているデータベースnum_doctors * num_timeperiods + 1回を照会するよりも速くすべきです。
編集:
(あなたが本当にモデルを変更することができない場合...)それはあなたの現在のモデル構造を動作させるために、あなたは私にあなたの答えを組み込んだ、と非常に似ていますビューで終わります私が書いた元のものへ。私はこれらのコメントがすべて上記のものと同じになるので、コメントをすべて削除しています。元のビューを変更した箇所にコメントを付けました。
def my_view(request):
doctors = GP.objects.all()
periods = get_time_periods()
smallest_date = get_smallest_date(time_periods)
largest_date = get_largest_date(time_periods)
# we make depth=3 so it spans via the PatientGPLink over to GP
deaths = Death.objects.select_related(depth=3).filter(date__range=(smallest_date, largest_date)).filter(patient__patientgplink__ismain=True)
results = dict((period,{doctor: 0}) for doctor in doctors for period in periods)
for death in deaths:
for period in time_periods:
if death.date > period['start_date'] and death.date < period['end_date']:
# and we change how we access the GP
results[period][death.patient.patientgplink.gp] += 1
まだ2つのクエリですが、これらのクエリはより大きい(複数のテーブルにまたがっています)。
医者のクエリーセットのコードを投稿できますか?とmy_new_queryset?そして最終的にモデル?ありがとう! – jpic
医師は、私はまだそれをやっていないセットまたはコレクションです。私の新しいクエリーセットは、私が問題を抱えているものです。 –