Django шаблон нескольких таблиц с немного измененными данными - PullRequest
0 голосов
/ 18 мая 2018

Я хочу отобразить две таблицы на моей странице, где изменен только один столбец, а все остальные одинаковы.Мне было интересно, есть ли другой способ, который более эффективен, чем простое повторение цикла два раза и создание таблицы два раза?

Что бы я сделал прямо сейчас:

# Example models
class Question(models.Model):
    question = models.TextField()

class Answer(models.Model):
    question = models.ForeignKey(Question)
    score = models.Integerfield()

    SCORETYPES = (
    (1, 'initial'),
    (2, 'current'),
    )

    scoreType = models.Integerfield(choices=SCORETYPES)

    def __str__(self):
        return "Answer: " + scoreType

В моемview Я бы связал вопрос с ответами так:

# Example view
questions = Question.objects.prefetch_related(Prefetch('answer_set', to_attr='answers')).all()

Что означает, что мой объект вопроса будет выглядеть так для каждого вопроса

question.answers = [<Answer: Initial>, <Answer: Current>]

, а затем в моем шаблоне я бынапечатать их так:

# Example template
{% for question in questions %}
    {% for answer in question.answers %}
        <p>{{ answer.scoreType }}: {{ answer.score }}</p>
    {% endfor %}
{% endfor %}

Это будет работать, но теперь я хочу создать таблицу для всех начальных результатов и одну таблицу для всех текущих результатов, чтобы вы получили что-то вроде этого:

Initial Scores

Question    Score
Q1          2
Q2          3

Current Scores

Question    Score
Q1          1
Q2          4

Как вы можете видеть, это потребовало бы от меня использовать цикл for два раза и каждый раз проверять, является ли тип оценки 1 или 2. Есть ли более эффективный способ сделать это или это путь?У меня много вопросов, и я хотел бы работать максимально эффективно.

Заранее спасибо!

1 Ответ

0 голосов
/ 18 мая 2018

Возможным решением будет использование двух разных наборов запросов, фильтр на Answer.scoreType, то есть:

# views

def myview(request, ...):
    qs = Question.objects.prefetch_related(Prefetch('answer_set', to_attr='answers'))
    initial = qs.filter(answer__scoreType=1)
    current = qs.filter(answer_scoreType=2)
    context = {"initial": initial, "current": current)
    # etc

Тогда

# template:

<h1>Initial scores</h1>
{% for q in initial %}
   {% for answer in q.answers %}
    # ...
   {% endfor %}
{% endfor %}

<h1>Current scores</h1>
{% for q in current %}
   {% for answer in q.answers %}
    # ...
   {% endfor %}
{% endfor %}

НО это означает, что у вас будет два дБзапросов, которые также могут быть неоптимальными (в зависимости от размера набора данных и т. д.).

Другим решением будет отфильтровать наборы запросов вручную в представлении, но это будет сложно, если вы хотите сохранить набор запросовупорядоченный по вопросу, будет потреблять больше памяти и, возможно, будет медленнее, чем два отдельных запроса (опять же, в зависимости от размера набора данных и т. д.).

Итак, если коротко, то "правильно«Решение действительно зависит от вашего фактического набора данных - особенно от того, сколько вопросов / ответов вы обычно имеете в виду.Если это очень маленькие наборы данных, фильтрация в представлении или даже непосредственно в шаблоне может быть достаточно быстрой, но относительная производительность чистого кода Python или (что еще хуже) шаблона шаблона против встроенной фильтрации базы данных SQL очень быстро сделает первый вариант (2 разных запроса) быстрее.

...