Один и тот же код оценки набора запросов, разные имена полей в 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.

Это дает желаемую таблицу:

введите описание изображения здесь

Однако я хотел бы спросить:

  1. Существует ли большая стоимость выполнения многократных оценок данных из удаленной базы данных? Насколько я понимаю, набор запросов bacteria = Bacteria.objects.all() кэшируется в памяти и может быть повторно оценен последующими запросами. Применимо ли это в данном случае?
  2. Код ужасно повторяется, где единственное, что меняется - это имена полей. Есть ли лучший способ организовать этот код?
  3. В конечном итоге, я хотел бы разрешить пользовательский ввод имен различных полей, а не вводить их жестко. Возможно ли заменить поля с точечной нотацией на лету? Спасибо.
  4. Фильтрация существующего набора запросов в этом случае делает дополнительный вызов к базе данных, поскольку первый набор запросов был оценен с помощью .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:
    
    Вернуться на верх