Один и тот же код оценки набора запросов, разные имена полей в Django Views
У меня есть кажущийся избыточным код в Django Views, который оценивает один и тот же набор запросов (Model.objects.all()), но с разными именами полей:
def overview_view(request):
bacteria = Bacteria.objects.all()
bacteria_count = bacteria.count()
bacteriaFilter = BacteriaFilter(request.GET, queryset=bacteria)
bacteria = bacteriaFilter.qs
remaining = bacteria.count()
glucose = []
not_glucose = []
pure_glucose = []
for bug in bacteria:
if (bug.glucose_acid_from is not None) and (bug.glucose_acid_from != 'neg'):
glucose.append(bug.species)
for bug in bacteria:
if (bug.glucose_use is not None) and (bug.glucose_use != 'neg'):
glucose.append(bug.species)
any_glucose = len(set(glucose))
for bug in bacteria:
if (bug.glucose_use is not None) and (bug.glucose_use == 'neg') and (bug.glucose_acid_from is not None) and (bug.glucose_acid_from == 'neg'):
not_glucose.append(bug.species)
no_glucose = len(set(not_glucose))
for bug in bacteria:
if (bug.glucose_use is not None) and (bug.glucose_use == '+'):
pure_glucose.append(bug.species)
for bug in bacteria:
if (bug.glucose_acid_from is not None) and (bug.glucose_acid_from == '+'):
pure_glucose.append(bug.species)
mix_glucose = any_glucose - len(set(pure_glucose))
nonr_glucose = bacteria_count - any_glucose
fructose = []
not_fructose = []
pure_fructose = []
for bug in bacteria:
if (bug.fructose_acid_from is not None) and (bug.fructose_acid_from != 'neg'):
fructose.append(bug.species)
for bug in bacteria:
if (bug.fructose_use is not None) and (bug.fructose_use != 'neg'):
fructose.append(bug.species)
any_fructose = len(set(fructose))
for bug in bacteria:
if (bug.fructose_use is not None) and (bug.fructose_use == 'neg') and (bug.fructose_acid_from is not None) and (bug.fructose_acid_from == 'neg'):
not_fructose.append(bug.species)
no_fructose = len(set(not_fructose))
for bug in bacteria:
if (bug.fructose_use is not None) and (bug.fructose_use == '+'):
pure_fructose.append(bug.species)
for bug in bacteria:
if (bug.fructose_acid_from is not None) and (bug.fructose_acid_from == '+'):
pure_fructose.append(bug.species)
mix_fructose = any_fructose - len(set(pure_fructose))
nonr_fructose = bacteria_count - any_fructose ...etc.
Я использую данные из этого представления для заполнения таблицы на html-странице:
<div>
<hr />
<table class="table table-sortable table-bordered table-hover">
<thead>
<p>Bacteria utilisation or oxidation/fermentation (O/F) of selected carbohydrates</p>
<tr>
<th>total</th>
<th>Carbohydrate</th>
<th>Any use or O/F</th>
<th>Mixed response (w, d, vr)</th>
<th>Neg for both</th>
<th>Neg or not reported</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{bacteria_count}}</td>
<td>glucose</td>
<td>{{any_glucose}}</td>
<td>{{mix_glucose}}</td>
<td>{{no_glucose}}</td>
<td>{{nonr_glucose}}</td>
</tr>
<tr>
<td>{{bacteria_count}}</td>
<td>fructose</td>
<td>{{any_fructose}}</td>
<td>{{mix_fructose}}</td>
<td>{{no_fructose}}</td>
<td>{{nonr_fructose}}</td>
</tr> ... etc.
Это дает желаемую таблицу:
введите описание изображения здесь
Однако я хотел бы спросить:
- Существует ли большая стоимость выполнения многократных оценок данных из удаленной базы данных? Насколько я понимаю, набор запросов
bacteria = Bacteria.objects.all()кэшируется в памяти и может быть повторно оценен последующими запросами. Применимо ли это в данном случае? Код ужасно повторяется, где единственное, что меняется - это имена полей. Есть ли лучший способ организовать этот код? - В конечном итоге, я хотел бы разрешить пользовательский ввод имен различных полей, а не вводить их жестко. Возможно ли заменить поля с точечной нотацией на лету? Спасибо.
Фильтрация существующего набора запросов в этом случае делает дополнительный вызов к базе данных, поскольку первый набор запросов был оценен с помощью .count(). Однако count() более эффективен, чем полный запрос, поэтому накладные расходы не так уж велики. Если вы не нуждаетесь в эффективности, это, вероятно, нормально.
Однако, несколько неэффективно циклически просматривать набор записей несколько раз, когда вы используете одни и те же зацикленные элементы и часто проверяете одни и те же вещи.
def overview_view(request): bacteria = Bacteria.objects.all() bacteria_count = bacteria.count()
bacteriaFilter = BacteriaFilter(request.GET, queryset=bacteria)
bacteria = bacteriaFilter.qs
remaining = bacteria.count()
glucose = []
not_glucose = []
pure_glucose = []
fructose = []
not_fructose = []
pure_fructose = []
for bug in bacteria:
if (bug.glucose_acid_from is not None):
if (bug.glucose_acid_from != 'neg'):
glucose.append(bug.species)
if (bug.glucose_use is not None) and (bug.glucose_use == 'neg') and (bug.glucose_acid_from == 'neg'):
not_glucose.append(bug.species)
if (bug.glucose_acid_from == '+'):
pure_glucose.append(bug.species)
if (bug.glucose_use is not None):
if (bug.glucose_use != 'neg'):
glucose.append(bug.species)
if (bug.glucose_use == '+'):
pure_glucose.append(bug.species)
if (bug.fructose_acid_from is not None):
if (bug.fructose_acid_from != 'neg'):
fructose.append(bug.species)
if (bug.fructose_use is not None) and (bug.fructose_use == 'neg') and (bug.fructose_acid_from == 'neg'):
not_fructose.append(bug.species)
if (bug.fructose_acid_from == '+'):
pure_fructose.append(bug.species)
if (bug.fructose_use is not None):
if (bug.fructose_use != 'neg'):
fructose.append(bug.species)
if (bug.fructose_use == '+'):
pure_fructose.append(bug.species)
any_glucose = len(set(glucose))
no_glucose = len(set(not_glucose))
mix_glucose = any_glucose - len(set(pure_glucose))
nonr_glucose = bacteria_count - any_glucose
any_fructose = len(set(fructose))
no_fructose = len(set(not_fructose))
mix_fructose = any_fructose - len(set(pure_fructose))
nonr_fructose = bacteria_count - any_fructose ...etc.
Для динамических имен полей вы можете попробовать:
str_variable = "glucose_acid_from"
bacteria = Bacteria.objects.all.values()
for bug in bacteria:
if bug[str_variable] is not None: