Django Python С Gspread: 'choices' должен быть итерабельным, содержащим (фактическое значение, читаемое человеком имя) кортежи
Я пытаюсь сделать что-то, что я никогда не видел сделанным раньше в django, я пытаюсь сделать поле модели (path_choices
), которое показывает все уникальные path_names
из моего листа google в поле выбора, чтобы пользователь мог выбрать один из них. Однако когда я попытался сделать поле выбора CharField, я получаю ошибку:
ERRORS:
dashboard.Robot.path_choices: (fields.E005) 'choices' must be an iterable containing (actual value, human readable name) tuples.
Прямо сейчас лист google, из которого я пытаюсь извлечь информацию с помощью gspread, имеет только два имени пути, так что если у кого-нибудь есть идеи о том, что вызывает эту проблему или что я могу сделать лучше, помощь будет оценена по достоинству! Мой код:
from django.db import models
import gspread
from oauth2client.service_account import ServiceAccountCredentials
class Robot(models.Model):
name = models.CharField(max_length=100)
status_choices = [('driving', 'driving'), ('waiting', 'waiting'), ('stuck', 'stuck')]
status = models.CharField(choices=status_choices, max_length=7, default='waiting')
scope = ["REDACTED",'REDACTED',"REDACTED","REDACTED"]
creds = ServiceAccountCredentials.from_json_keyfile_name("dashboard/Files/creds.json", scope)
client = gspread.authorize(creds)
sheet = client.open("tutorial").sheet1
path_name_fetch = sheet.col_values(1)
path_names = []
temp_list = []
path_options = []
for i in path_name_fetch:
if i not in path_names:
path_names.append(i)
for path_name_options in path_names:
temp_list.append(f'{path_name_options}')
temp_list.append(f'{path_name_options}')
path_options.append(tuple(temp_list))
path_choices = models.CharField(choices=path_options, max_length=20, default='Default')
То, что вы пытаетесь сделать, может не соответствовать предполагаемому использованию Choices
. Всякий раз, когда возможности Choice
изменяются на уровне Model
, должны быть сделаны новые миграции.
Ваша реализация Choice
для Robot.status
является статичной и соответствует примеру в документации Django.
Если вместо этого вы хотите использовать динамический Choice
для вашего path_choices
, получаемого из Google Sheets, я бы рекомендовал сделать это в ModelForm с помощью ChoiceField
.
Согласно документации, доступные варианты могут быть получены из вызываемого объекта, который будет представлять собой ваш path_options
, обернутый в функцию. Тогда path_options
должен стать CharField
без выбора, поскольку вы управляете им в представлении, а не на уровне модели.
class Robot(models.Model):
...
path_choices = models.CharField(max_length=255)
class RobotForm(ModelForm):
def _generate_choices():
# Query GSpread
choices = [('choice','choice'), ...]
return choices
path_choices = forms.ChoiceField(choices=_generate_choices())
class Meta:
model = Robot
fields = ['path_choices', ...]