Этот вопрос был SOLVED, после того как он лучше посмотрел на него. Пожалуйста, прочтите мой ответ ниже.
Я получаю "Параметр fields
должен быть списком или кортежем. Got str." при запуске моего приложения Django.
Выполняя точно такой же код с отладчиком, и если у меня есть точка останова в строке ошибки, то это не сработает, и что должно быть кортежем, похоже, является кортежем.
Проблема, похоже, находится в следующем коде внутри DRF ModelSerializer:
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
# Instantiate the superclass normally
super(ChHiveLevel1Serializer, self).__init__(*args, **kwargs)
if fields is not None:
# Drop fields that are specified in the `fields` argument.
for field_name in fields:
self.fields.pop(field_name)
print("fields to be included: ", self.fields)
В views.py я просто делаю: ...
hives = profile.hive_subscriptions
# En fields se le pasa el campo a eliminar del serializador
fields = ('priority', )
serializer = serializers.ChHiveLevel1Serializer(hives, fields=fields, many=True)
...
И это трассировка:
Internal Server Error: /profiles/diegoocampo8/hives/
Traceback (most recent call last):
File "/home/diego/virtualenvs/chattyhive3.3.4/lib/python3.3/site-packages/django/core/handlers/base.py", line 111, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/diego/virtualenvs/chattyhive3.3.4/lib/python3.3/site-packages/django/views/decorators/csrf.py", line 57, in wrapped_view
return view_func(*args, **kwargs)
File "/home/diego/virtualenvs/chattyhive3.3.4/lib/python3.3/site-packages/django/views/generic/base.py", line 69, in view
return self.dispatch(request, *args, **kwargs)
File "/home/diego/virtualenvs/chattyhive3.3.4/lib/python3.3/site-packages/rest_framework/views.py", line 452, in dispatch
response = self.handle_exception(exc)
File "/home/diego/virtualenvs/chattyhive3.3.4/lib/python3.3/site-packages/rest_framework/views.py", line 449, in dispatch
response = handler(request, *args, **kwargs)
File "/home/diego/PycharmProjects/chattyhive/API/views.py", line 271, in get
serializer = serializers.ChHiveLevel1Serializer(hives, fields=fields, many=True)
File "/home/diego/virtualenvs/chattyhive3.3.4/lib/python3.3/site-packages/rest_framework/serializers.py", line 96, in __new__
return cls.many_init(*args, **kwargs)
File "/home/diego/virtualenvs/chattyhive3.3.4/lib/python3.3/site-packages/rest_framework/serializers.py", line 116, in many_init
child_serializer = cls(*args, **kwargs)
File "/home/diego/PycharmProjects/chattyhive/API/serializers.py", line 274, in __init__
print("fields to be included: ", self.fields)
File "/home/diego/virtualenvs/chattyhive3.3.4/lib/python3.3/site-packages/rest_framework/utils/serializer_helpers.py", line 120, in __repr__
return dict.__repr__(self.fields)
File "/home/diego/virtualenvs/chattyhive3.3.4/lib/python3.3/site-packages/rest_framework/serializers.py", line 611, in __repr__
return unicode_to_repr(representation.list_repr(self, indent=1))
File "/home/diego/virtualenvs/chattyhive3.3.4/lib/python3.3/site-packages/rest_framework/utils/representation.py", line 97, in list_repr
if hasattr(child, 'fields'):
File "/home/diego/virtualenvs/chattyhive3.3.4/lib/python3.3/site-packages/rest_framework/serializers.py", line 313, in fields
for key, value in self.get_fields().items():
File "/home/diego/virtualenvs/chattyhive3.3.4/lib/python3.3/site-packages/rest_framework/serializers.py", line 837, in get_fields
field_names = self.get_field_names(declared_fields, info)
File "/home/diego/virtualenvs/chattyhive3.3.4/lib/python3.3/site-packages/rest_framework/serializers.py", line 889, in get_field_names
type(fields).__name__
TypeError: The `fields` option must be a list or tuple. Got str.
[05/May/2015 17:30:34] "GET /profiles/diegoocampo8/hives/ HTTP/1.1" 500 136024
Если я удалю print("fields to be included: ", self.fields)
, то я получаю ту же ошибку, но он будет указывать на строку serializer = serializers.ChHiveLevel1Serializer(hives, fields=fields, many=True)
в views.py
Хорошо, я все еще ноб в Python, и я мог бы сделать что-то очень не так, но я не могу понять, почему, если я вставляю точку останова в печать, о которой я только что упомянул, и я делаю то же api запрос с отладкой, тогда код просто работает: я получаю свой ответ так, как я хотел, и он не дает никакой ошибки (если я удалю точку останова, он снова даст ошибку, даже если запуск с отладчиком).
Вы, ребята, знаете, что может быть неправильно? Заранее большое спасибо. Спросите меня о дополнительной информации, если вам это нужно.
EDIT: дополнительные пояснения:
Весь сериализатор:
class ChHiveLevel1Serializer(serializers.ModelSerializer):
"""Used by the following API methods: GET hive list,
"""
category = serializers.SlugRelatedField(read_only=True, slug_field='code')
languages = serializers.SlugRelatedField(source='_languages', many=True, read_only=True, slug_field='language')
# If in the POST we only need to establish the relationship with User model (not update the model itself) we
# set read_only to True
creator = serializers.SlugRelatedField(read_only=True, slug_field='public_name')
tags = serializers.SlugRelatedField(many=True, read_only=True, slug_field='tag')
public_chat = ChPublicChatLevel1Serializer(many=False, read_only=True)
community_public_chats = ChCommunityPublicChatLevel1Serializer(many=True, read_only=True)
subscribed_users_count = serializers.IntegerField(source='get_subscribed_users_count', read_only=True)
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
# Instantiate the superclass normally
super(ChHiveLevel1Serializer, self).__init__(*args, **kwargs)
if fields is not None:
# Drop fields that are specified in the `fields` argument.
for field_name in fields:
self.fields.pop(field_name)
print("fields to be included: ", self.fields)
class Meta:
model = ChHive
fields = ('name', 'slug', 'description', 'category', 'languages', 'creator', 'creation_date', 'tags',
'priority', 'type', 'public_chat', 'community_public_chats', 'subscribed_users_count')
Я знаю, что сбивает с толку 3 разных поля, поэтому я разъясняю это:
в представлениях я передаю param 'поля' в сериализатор, это кортеж, который содержит имена полей, которые будут динамически удаляться из сериализатора. Затем внутри init я вывожу этот параметр (поэтому он не отправляется в суперкласс) и присваивает ему поля локального кортежа. Наконец, внутри полей "if" не "None" я удаляю из self.fields(это поля, определенные в сериализаторе) поля с именем, соответствующим именам внутри локального кортежа. Надеюсь, теперь я смогу объяснить это лучше.
Вот видео, показывающее, как при отладке и остановке в точке останова это просто работает: http://youtu.be/RImEMebBGLY