Как написать запрос, чтобы узнать, сколько раз выбор был выбран пользователями - PullRequest
0 голосов
/ 09 апреля 2020

Я хочу посчитать, сколько раз выбор был выбран пользователями. Вот моя модель

models.py

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from multiselectfield import MultiSelectField


class MedicalHistory(models.Model):
    Anxiety = 'Anxiety'
    Arthritis = 'Arthritis'
    Asthma = 'Asthma'
    Anemia = 'Anemia'
    Cancer = 'Cancer'
    Corona_virus = 'Corona_virus'
    Diabetes = 'Diabetes'
    Ebola = 'Ebola'
    HIV = 'HIV'
    ILLNESS_CHOICES = (
        (Anxiety, "Anxiety"),
        (Arthritis, "Arthritis"),
        (Asthma, "Asthma"),
        (Anemia, "Anemia"),
        (Cancer, "Cancer"),
        (Corona_virus, "Corona_virus"),
        (Diabetes, "Diabetes"),
        (Ebola, "Ebola"),
        (HIV, "HIV"),
    )
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    illness = MultiSelectField(choices=ILLNESS_CHOICES, max_length=50)
    symptoms = models.CharField(max_length=100)
    additional_info = models.CharField(max_length=100)
    disability = models.BooleanField(default=False)
    medications = models.BooleanField(default=False)
    created_at = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return f'{self.user.username} Medical History'

Здесь у меня есть ряд болезней, из которых я хочу выбрать пользователей. Пользователь может выбрать более одного загара. Я хочу, чтобы каждая болезнь имела счет, и каждый раз, когда болезнь выбирается, она добавляет к счету. На мой взгляд, у меня есть

views.py

def pie_chart(request):
labels = []
data = []

queryset = MedicalHistory.objects.values('illness').annotate(count=Sum('user')).order_by('-count')
for entry in queryset:
    labels.append(entry['illness'])
    data.append(entry['count'])

    return JsonResponse(data={
        'labels': labels,
        'data': data,
    }) 

<QuerySet [{'illness': ['Asthma', 'Diabetes', 'Ebola'], 'count': 3}, {'illness': ['Anemia', 'Covid-19'], 'count': 2}]>

Запрос не выполняет то, что я хочу, так как я пытаюсь построить его на диаграмме. Это группирует болезнь, я думаю из-за values. Мой шаблон. html выглядит следующим образом.

chart. html

{% block content %}
{% include 'sidebar.html' %}
<div id="container" style="width: 85%;">
    <canvas id="myChart"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
<script>
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: {{ labels|safe }},
        datasets: [{
            label: 'Overview of Medical History',
            data: {{ data|safe }},
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(225, 400, 64, 0.2)'

            ],
            borderColor: [
                'rgba(255, 99, 132, 1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 206, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
                'rgba(255, 159, 64, 1)'

            ],
            borderWidth: 1
        }]
    },
    options: {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero: true
                }
            }]
        }
    }
});
</script>

        </div>
     <!-- /#page-content-wrapper -->
</div>
  <!-- /#wrapper -->
{% endblock %}

Решение:

Итак, я смог решить эту проблему, используя python. Я инициализировал dict с болезнями и установил их начальный счет как 0. Затем я использовал values ​​() возвращает словарь болезней, сохраненный в БД. Я перебрал набор запросов и соединил 1 со значениями болезней. Затем я передал ключи и значения в виде меток и данных соответственно.

views.py

def pie_chart(request):
    count = {'Anxiety': 0, 'Arthritis': 0, 'Asthma': 0, 'Anemia': 0, 'Cancer': 0,
             'Corona_virus': 0, 'Diabetes': 0, 'Ebola': 0, 'HIV': 0
             }

    queryset = MedicalHistory.objects.values('illness')
    for entry in queryset:
        for values in entry['illness']:
            count[values] += 1

    labels = [*count.keys()]
    data = [*count.values()]

    return render(request, 'chart.html', {
        'labels': labels,
        'data': data,
    })

1 Ответ

1 голос
/ 09 апреля 2020

Вы не можете сделать это на уровне базы данных, если используете MultiSelectField, потому что базовое значение просто хранится как CharField в базе данных. Таким образом, values('illness') будет группировать только по равным строкам, т. Е. Комбинациям болезней.

Так что либо сделайте это в python, после того как вы получите все экземпляры: счетчики, l oop через экземпляры в вашем наборе запросов и обновите счетчики один за другим. Примечание. Это не будет масштабироваться, когда количество MedicalHistory строк в вашей таблице станет большим.

Или смоделируйте Illness как отдельную модель (не используйте MultiSelectField), используйте ManyToMany отношения и считай тех. Затем вы можете сделать это в наборе запросов. Это будет масштабироваться с очень большим количеством строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...