Мне нужно создать модель Django CitiesVisited с MultiSelectField , которая будет содержать все города для данной страны, взятые из файла JSON. Сохраненные объекты должны выглядеть так:
Django просмотр админки городов посещенного объекта
Чтобы для каждой страны (модель «CitiesVisitedCountry») каждый пользователь мог сохранить города, которые он посетил.
Models.py
class CitiesVisitedCountry(models.Model):
""" Every user can have multiple countries visited. Each instance of this class will save oen country """
user = models.ForeignKey(User, on_delete=models.CASCADE)
country_name = models.CharField(max_length=50)
def __str__(self):
return f"{self.country_name}"
class Meta:
""" define nemes to be displayed on admin page """
verbose_name = "Country visited"
verbose_name_plural = "Countries visited"
class CitiesVisited(models.Model):
""" For each country visited, save selection of cities visited """
user = models.ForeignKey(User, on_delete=models.CASCADE)
country = models.ForeignKey(CitiesVisitedCountry, on_delete=models.CASCADE)
cities = MultiSelectField(choices=select_cities_options("Austria"), null=True, blank=True)
def __str__(self):
return f"visited cities for country {self.country} checkbox"
class Meta:
""" define nemes to be displayed on admin page """
verbose_name_plural = "Cities visited checkbox multiple selections"
Проблема в том, что я вынужден использовать список по умолчанию для заполнения вариантов выбора (например, я использую Австрию), и я не могу переопределить этот список при создании объекта.
select_cities_options ( «Австрия»)
def select_cities_options(country_in):
"""
country_in = 'United States'
Returns a list with tuple of cities for country_in. Will be used to populate city by country drop-down menus.
"""
options_by_country = []
with open(os.path.join(BASE_DIR, 'user_maps', 'static', 'user_maps', 'cities_by_country.json'), mode='r') as file:
content = json.load(file)
for country in content:
if country == str(country_in):
for city in content[country]:
options_by_country.append((city, city))
return options_by_country
В моем views.py я пытаюсь создать новый объект CitiesVisited, который использует список городов Италии. Этот список параметров должен заменить сохраненный по умолчанию для Австрии. views.py
country_related_object = CitiesVisitedCountry.objects.filter(
user=request.user, country_name="United States").first()
existing_visited_cities_object = CitiesVisited(
user=request.user, country=country_related_object,
cities=MultiSelectField(choices=select_cities_options(visited_country))
)
print(existing_visited_cities_object.cities.choices)
existing_visited_cities_object.save()
print(existing_visited_cities_object.cities.choices)
правильно печатает новые параметры:
[('Abano Terme', 'Abano Terme'), ('Abbadia Lariana', 'Abbadia Lariana'), ('Abbadia San Salvatore', 'Abbadia San Salvatore'), ...
Однако, когда я пытаюсь сохранить объект с помощью existing_visited_cities_object.save()
I получите эту ошибку:
Internal Server Error: /places_visited/
Traceback (most recent call last):
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\contrib\auth\mixins.py", line 52, in dispatch
return super().dispatch(request, *args, **kwargs)
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\views\generic\base.py", line 97, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\ventafri\Desktop\Repositories\Personal\Holiday Planner\Holiday_Planner\holiday_planner\user_maps\views.py", line 119, in get
existing_visited_cities_object.save()
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 746, in save
force_update=force_update, update_fields=update_fields)
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 784, in save_base
force_update, using, update_fields,
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 887, in _save_table
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 926, in _do_insert
using=using, raw=raw,
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\query.py", line 1204, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1391, in execute_sql
for sql, params in self.as_sql():
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1336, in as_sql
for obj in self.query.objs
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1336, in <listcomp>
for obj in self.query.objs
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1335, in <listcomp>
[self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1276, in prepare_value
value = field.get_db_prep_save(value, connection=self.connection)
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\fields\__init__.py", line 821, in get_db_prep_save
return self.get_db_prep_value(value, connection=connection, prepared=False)
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\multiselectfield\db\fields.py", line 145, in get_db_prep_value
value = self.get_prep_value(value)
File "C:\Users\ventafri\AppData\Local\Programs\Python\Python36\lib\site-packages\multiselectfield\db\fields.py", line 141, in get_prep_value
return '' if value is None else ",".join(map(str, value))
TypeError: 'MultiSelectField' object is not iterable
Как правильно сохранить новый объект CitiesVisited, чтобы он правильно отображал новый правильный список городов для страны, на которую он ссылается?
Спасибо