我需要提高这段代码的处理速度:
score_forms = InstrumentScore.objects.filter(instrument=study_obj.instrument)
for administration_data_item in administration_data.objects.filter(administration_id=administration_id):
inst = Instrument_Forms.objects.get(instrument=study_obj.instrument,itemID=administration_data_item.item_ID)
scoring_category = inst.scoring_category if inst.scoring_category else inst.item_type
for f in score_forms: #items can be counted under multiple Titles check category against all categories
if f.kind == "count" :
if scoring_category in f.category.split(';'):
if administration_data_item.value in f.measure.split(';'): #and check all values to see if we increment
scoring_dict[f.title] += 1
else :
if scoring_category in f.category.split(';'):
scoring_dict[f.title] += administration_data_item.value + '\n'
问题在于它可以访问许多表,并且这些表并不总是在外键上链接,而是通过提供一个引用其他模型中的记录的CharField来链接它们。如何在不更改数据库结构的情况下改进此处理?
模型
class administration_data(models.Model):
administration = models.ForeignKey("administration") # Associated administration
item_ID = models.CharField(max_length = 101) # ID associated for each CDI item
value = models.CharField(max_length=200) # Response given by participant to this particular item
class Meta:
unique_together = ('administration', 'item_ID') # Each administation_data object must have a unique combination of administration ID and item ID.
def __unicode__(self):
return '%s %s' % (self.administration, self.item_ID)
class Instrument_Forms(models.Model):
instrument = models.ForeignKey('researcher_UI.instrument', db_index=True)
itemID = models.CharField(max_length = 101, db_index=True) # ID number for identification
item = models.CharField(max_length = 101) # string variable name
item_type = models.CharField(max_length = 101) # type of variable (word, phrase, etc.)
category = models.CharField(max_length = 101) # if word, the subcategory for item (animals, sounds, etc.)
choices = models.ForeignKey('Choices', null=True, on_delete=models.deletion.PROTECT)
definition = models.CharField(max_length = 1001, null=True, blank=True) # item listed in plaintext. This is what is displayed to test-takers along with possible choices
gloss = models.CharField(max_length = 1001, null=True, blank=True) # English translation for item. At the moment, we only have English instruments so definition and gloss are identical
complexity_category = models.CharField(max_length = 101, null=True, blank=True) # category for complexity item. Currently blank.
uni_lemma = models.CharField(max_length= 101, null=True, blank=True) # ID for matching terms across languages. Currently unused.
item_order = models.IntegerField(validators=[MinValueValidator(1)])
scoring_category = models.CharField(max_length = 101, null=True, blank=True) # used to provide scoring granulatity - uses item_type if blank
def __unicode__(self):
return "%s (%s, %s)" % (self.definition, self.instrument.verbose_name, self.itemID)
class Meta:
unique_together = ('instrument', 'itemID') # Each instrument in the database must have a unique combination of instrument and itemID
class InstrumentScore(models.Model):
'''
Class to store the instrument scoring mechanisms loaded from json files held in
/cdi_forms/form_data/scoring/
'''
instrument = models.ForeignKey(instrument, on_delete=models.CASCADE)
title = models.CharField(max_length=101)
category = models.CharField(max_length=101)
measure = models.CharField(max_length=101)
order = models.IntegerField(default=999)
kind = models.CharField(max_length=5, default="count", choices=KIND_OPTIONS)
def __unicode__(self):
return '%s: %s' % (self.instrument, self.title)
class Meta:
ordering = ['instrument', 'order']
class instrument(models.Model):
name = models.CharField(max_length = 51, primary_key=True) # Instrument short name
verbose_name = models.CharField(max_length = 51, blank = True) # Instrument official title
language = models.CharField(max_length = 51) # Instrument's language. For 'English Words & Sentences' this would be 'English'
form = models.CharField(max_length = 51) # Instrument's form type abbreviation. For 'English Words & Sentences' this would be 'WS'
min_age = models.IntegerField(verbose_name = "Minimum age") # Minimum age in months that instrument was built for
max_age = models.IntegerField(verbose_name = "Maximum age") # Maximum age in months that instrument was built for
def __unicode__(self):
return "%s (%s %s)" % (self.verbose_name, self.language, self.form)
def __str__(self):
return unicode(self).encode('utf-8')
class Meta:
unique_together = ('language', 'form') # Each instrument in the database must have a unique combination of language and form type
class study(models.Model):
researcher = models.ForeignKey("auth.user") # Researcher's name
name = models.CharField(max_length = 51) # Study name
instrument = models.ForeignKey("instrument") # Instrument associated with study
waiver = models.TextField(blank = True) # IRB Waiver of documentation for study or any additional instructions provided to participant
study_group = models.CharField(max_length = 51, blank = True) # Study group
anon_collection = models.BooleanField(default=False) # Whether participants in study will all be anonymous
subject_cap = models.IntegerField(blank = True, null=True) # Subject cap to limit number of completed administrations
confirm_completion = models.BooleanField(default=False) # Whether to have participant confirm child's age and that test was completed to best of ability at end of study
allow_payment = models.BooleanField(default=False) # Whether to reward participants with gift card codes upon completion
allow_sharing = models.BooleanField(default=False) # Whether to allow participants to share results via Facebook
test_period = models.IntegerField(default=14, validators = [MinValueValidator(1), MaxValueValidator(28)]) # Number of days after test creation that a participant may work on and complete administration
prefilled_data = models.IntegerField(default=0)
min_age = models.IntegerField(verbose_name = "Minimum age", blank = True, null=True) # Minimum age in months for study
max_age = models.IntegerField(verbose_name = "Maximum age", blank = True, null=True) # Maximum age in months for study
birth_weight_units = models.CharField(max_length = 5, default="lb")
show_feedback = models.BooleanField(default=True)
active = models.BooleanField(default=True)
def __unicode__(self):
return self.name
def __str__(self):
return unicode(self).encode('utf-8')
答案 0 :(得分:1)
这将我正在处理的示例数据的时间减少了4
for f in score_forms: #and ensure each score is at least 0
insts = Instrument_Forms.objects.filter(instrument=study_obj.instrument, scoring_category__in=f.category.split(';'))
insts_IDs = []
for inst in insts: insts_IDs.append(inst.itemID)
if f.kind == 'count' :
scoring_dict[f.title] = administration_data.objects.filter(administration_id=administration_id, value__in=f.measure.split(';'), item_ID__in=insts_IDs).count()
else :
items = administration_data.objects.filter(administration_id=administration_id, item_ID__in=insts_IDs)
scoring_dict[f.title] = ''
for item in items :
scoring_dict[f.title] += item.value + '\n'