2016-08-17 7 views
4

В моих моделях, у меня есть следующие классы:Проводка внешнего ключа в Джанго Rest Framework

class Topic(models.Model): 
    name = models.CharField(max_length=25, unique=True) 

class Content(models.Model): 
    title = models.CharField(max_length=255) 
    body = models.TextField() 
    topic = models.ForeignKey(Topic, blank=True, null=True) 

Мои сериализаторы как это:

class TopicSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Topic 
     fields = ('name') 

class ContentSerializer(serializers.ModelSerializer): 
    topic = TopicSerializer(read_only=True) 
    class Meta: 
      model = Content 
      fields = ('title', 'body', 'topic') 

Хорошо, так что в мой URL-адрес файл, у меня есть следующий шаблон:

urlpatterns = [ 
    ... 
    url(r'^api/topic_detail/(?P<name>[a-zA-Z0-9-]+)/content_list/$', views.topic_content_list, name='topic_content_list'), 
    ... 
] 

Поэтому, когда пользователь говорит /api/topic_detail/sports/content_list/, мы получаем список всех материалов, содержащих тему sports. Теперь я хочу, чтобы мы получили POST следующие данные по вышеуказанному URL-адресу, а затем объект контента создан с соответствующим полем, связанным автоматически с спортом.

Я пытаюсь сделать это следующим образом в моих просмотров:

@api_view(['GET', 'POST']) 
def topic_content_list(request, name): 
    try: 
     topic = Topic.objects.get(name=name) 
    except: 
     return Response(status=status.HTTP_404_NOT_FOUND) 

    if request.method == 'GET': 
     contents = Content.objects.filter(topic=topic) 
     serializer = ContentSerializer(contents, many=True) 
     return Response(serializer.data) 

    elif request.method == 'POST': 
     request.data["topic"] = topic 
     serializer = ContentSerializer(data=request.data) 
     print request.data 
     if serializer.is_valid(): 
      serializer.save() 
      return Response(serializer.data, status=status.HTTP_201_CREATED) 
     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

Теперь давайте говорить я иду URL /api/topic_detail/sports/content_list/ и POST это:

{ 
    "title": "My blog post", 
    "body" : ".....", 
} 

Объект контент будет создаваться и поле заголовка и тела установлено правильно. Однако в поле темы установлено значение null. Как я могу это исправить? Любая помощь приветствуется.

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

EDIT

Хорошо, так что я установил свою тупую ошибку:

class ContentSerializer(serializers.ModelSerializer): 
    topic = TopicSerializer(read_only=False) 
    class Meta: 
      model = Content 
      fields = ('title', 'body', 'topic') 

То есть, я установить READ_ONLY аргумент в значение False. Тем не менее, в настоящее время пост создает новую ошибку:

{ 
    "topic": { 
     "non_field_errors": [ 
      "Invalid data. Expected a dictionary, but got Topic." 
     ] 
    } 
} 

Это я уверен, относится к тому факту, что data.website я посылаю в не JSON, но вместо этого просто экземпляра модели Django. Как я могу JSONify одного экземпляра?

ответ

4

Это из вашего сериализатора.

 topic = TopicSerializer(read_only=True) 

Это означает, что ваша тема читается только так, когда вы пытаетесь сохранить сериалайзер, тема не получает спасение. Удалите это, и проблема будет исправлена.

EDIT:

Теперь, как на второй ошибки, это потому, что ожидает Dict и вы передаете экземпляр модели, поэтому у вас есть два варианта. Либо создайте dict вручную.

topic_dict = { "name": topic.name }

и передать как 'тему' в запросе.данных, а затем сохраните или передайте topic_id, так как есть отношение внешнего ключа, оно должно работать.

Так было бы что-то вроде:

request.data["topic_id"] = topic.id 

Теперь то, что вы хотите сделать, это полностью Шифрование до вас.

+0

спасибо. Я добавил редактирование, вы можете помочь? –

+0

Nvm, я должен задать другой вопрос, поскольку проблема другая. –

+0

Только что обновил мой ответ. –