Как сопоставить ключи словаря с идентификаторами моделей - PullRequest
0 голосов
/ 27 июня 2018

У меня есть список, подобный следующему: my_list = ['1', '2', '1', '3', '2', '1']

Это голоса, и каждый голос соответствует идентификатору из этой модели, который содержит варианты опроса:

class Choice(models.Model):
    question = models.ForeignKey(Poll, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)

Я использую Счетчик для подсчета голосов, и я получаю следующее:

>>>votes = Counter(my_list)
>>>print(votes)
Counter({'1': 3, '2': 2, '3': 1})

Каждый ключ в этом словаре соответствует идентификатору в модели Choice. Как заменить имена ключей словаря соответствующими choice_text для каждого идентификатора? Я хотел бы закончить со словарем, который выглядит следующим образом:

{'choice_text for id=1':3, 'choice_text for id=2':2, 'choice_text for id=3':1}

РЕДАКТИРОВАТЬ: Кроме того, что, если я хотел бы сделать ту же процедуру для списка, который у меня уже есть.

my_list = ['1', '2', '1', '3', '2', '1']

примерно так:

another_list = ['choice_text for id=1', 'choice_text for id=2', 'choice_text for id=1', 'choice_text for id=3', 'choice_text for id=2', 'choice_text for id=1']

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Ну, мы можем сначала загрузить словарь, который отображает id s на choice_text:

mapping = dict(Choice.objects.filter(pk__in=votes.keys())
                             .values_list('pk', 'choice_text'))

Здесь с pk__in мы, таким образом, создаем фильтр (который, строго говоря, не является необходимым, но уменьшит объем работы как для базы данных, так и для веб-сервера, если количество id s не огромно). Затем мы хотим, чтобы он возвращал values_list с, поэтому для каждого элемента список с двумя элементами: pk и choice_text.

Мы используем конструктор dict(..), который может извлечь итерацию из 2-х списков (или 2-кортежей) и преобразовать его в словарь, где для каждого элемента левый элемент подсписка / кортежа является ключом, и правильный элемент - это значение.

Теперь мы можем использовать это для создания нового словаря:

votes_with_text = {mapping[int(k)]: v for k, v in votes.items()}

Обратите внимание, что если есть два Choice с одинаковыми choice_text, то в нем будет сохранено только один элементов в счетчике.

В случае, если choice_text должны быть разными для каждых двух Choice с одинаковыми question, вы можете применить это на уровне модели с помощью unique_together:

class Choice(models.Model):
    question = models.ForeignKey(Poll, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)

    class Meta:
       <b>unique_together = (('question', 'choice_text'), )</b>
0 голосов
/ 27 июня 2018

, чтобы получить имя по вашему выбору:

choice_text = Choice.objects.get(pk=choice_id)

, поэтому вам нужно перебрать свои идентификаторы, получить выбор_текста и использовать:

votes[choice_text] = votes.pop(choice_id) переименовать ваши ключи в соответствующие имена выбора.

...