Django-Rest-Framework更新外键BY Id

aka*_*nom 9 django django-rest-framework

我正在使用django-rest-framework来构建后端.我的列表运行正常,但(使用django-rest-framework管理屏幕)我不能通过使用外键对象的Id字段来创建对象.我希望我的配置不正确,但我愿意写一些代码,如果我必须:)我正在从.NET和Java背景学习django/python,可能已成为这个新栈的宠坏.

编辑:我试图不使用两个不同的模型类 - 我不应该对吗?

提前致谢.

来自Chrome - 请求的关键位

Request URL:http://127.0.0.1:8000/rest/favorite_industries/ 
Request Method:POST 
_content_type:application/json
_content:{
    "user_id": 804    ,"industry_id": 20 }
Run Code Online (Sandbox Code Playgroud)

响应

HTTP 400 BAD REQUEST
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, POST, HEAD, OPTIONS

{
    "user": [
        "This field is required."
    ]
}
Run Code Online (Sandbox Code Playgroud)

啊.以下是django的关键类:

class FavoriteIndustry(models.Model):
    id = models.AutoField(primary_key=True)
    user = models.ForeignKey(User, related_name='favorite_industries')
    industry = models.ForeignKey(Industry)

    class Meta:
        db_table = 'favorites_mas_industry'

class FavoriteIndustrySerializer(WithPkMixin, serializers.HyperlinkedModelSerializer):
    class Meta:
        model = myModels.FavoriteIndustry
        fields = (
            'id'
            , 'user'
            , 'industry'
        )
Run Code Online (Sandbox Code Playgroud)

编辑添加视图集:

class FavoriteIndustriesViewSet(viewsets.ModelViewSet):
    #mixins.CreateModelMixin, viewsets.GenericViewSet):
    paginate_by = 1
    queryset = myModels\
        .FavoriteIndustry\
        .objects\
        .select_related()
    print 'SQL::FavoriteIndustriesViewSet: ' + str(queryset.query)
    serializer_class = mySerializers.FavoriteIndustrySerializer
Run Code Online (Sandbox Code Playgroud)

get/list功能生成了不错的JSON:

{"count":2,"next":" http://blah.com/rest/favorite_industries/?page=2&format=json ","previous":null,"results":[{"id":1, "user":" http://blah.com/rest/users/804/ ","industry":{"industry_id":2,"industry_name":"Consumer Discretionary","parent_industry_name":"Consumer Discretionary", "category_name":"行业"}}]}

Azi*_*ari 37

我已经创建了一个简化的应用程序模拟.

models.py:

from django.db import models
from django.contrib.auth.models import User

class Industry(models.Model):
    name = models.CharField(max_length=128)

class FavoriteIndustry(models.Model):
    user = models.ForeignKey(User, related_name='favorite_industries')
    industry = models.ForeignKey(Industry)
Run Code Online (Sandbox Code Playgroud)

views.py:

from rest_framework import viewsets
from models import FavoriteIndustry
from serializers import FavoriteIndustrySerializer

class FavoriteIndustriesViewSet(viewsets.ModelViewSet):
    queryset = FavoriteIndustry.objects.all()
    serializer_class = FavoriteIndustrySerializer
Run Code Online (Sandbox Code Playgroud)

serializers.py:

from rest_framework import serializers
from models import FavoriteIndustry, Industry

class FavoriteIndustrySerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = FavoriteIndustry
        fields = ('id', 'user', 'industry')
Run Code Online (Sandbox Code Playgroud)

urls.py:

from django.conf.urls import patterns, include, url
from core.api import FavoriteIndustriesViewSet

favorite_industries_list = FavoriteIndustriesViewSet.as_view({
    'get': 'list',
    'post': 'create'
})

urlpatterns = patterns('',
    url(r'^favorite_industries/$', favorite_industries_list, name='favorite-industries-list'),
    url(r'^users/(?P<pk>[0-9]+)/$', favorite_industries_list, name='user-detail'),
    url(r'^industries/(?P<pk>[0-9]+)/$', favorite_industries_list, name='industry-detail'),
)
Run Code Online (Sandbox Code Playgroud)

以下是一些测试:

>>> 
>>> import json
>>> from django.test import Client
>>> from core.models import Industry
>>> 
>>> industry = Industry(name='candy')
>>> industry.save()
>>> 
>>> c = Client()
>>> 
>>> response = c.get('http://localhost:8000/favorite_industries/')
>>> response.content
'[]'
>>> 
>>> data = {
...     'user': 'http://localhost:8000/users/1/',
...     'industry': 'http://localhost:8000/industries/1/'
... }
>>> 
>>> response = c.post('http://localhost:8000/favorite_industries/', json.dumps(data), 'application/json')
>>> response.content
'{"id": 1, "user": "http://testserver/users/1/", "industry": "http://testserver/industries/1/"}'
>>> 
>>> response = c.get('http://localhost:8000/favorite_industries/')
>>> response.content
'[{"id": 1, "user": "http://testserver/users/1/", "industry": "http://testserver/industries/1/"}]'
>>> 
Run Code Online (Sandbox Code Playgroud)

Django REST Framework期望user并且industry在您使用之后将字段作为URL而不是ID HyperlinkedModelSerializer.


使用ID

如果您需要使用对象ID而不是URL,请使用ModelSerializer而不是将HyperlinkedModelSerializerand传递给userindustry:

serializers.py:

from rest_framework import serializers
from models import FavoriteIndustry, Industry

class FavoriteIndustrySerializer(serializers.ModelSerializer):
    class Meta:
        model = FavoriteIndustry
        fields = ('id', 'user', 'industry')
Run Code Online (Sandbox Code Playgroud)

并测试:

>>> 
>>> import json
>>> from django.test import Client
>>> from core.models import Industry
>>> 
>>> #industry = Industry(name='candy')
>>> #industry.save()
>>> 
>>> c = Client()
>>> 
>>> response = c.get('http://localhost:8000/favorite_industries/')
>>> response.content
'[{"id": 1, "user": 1, "industry": 1}, {"id": 2, "user": 1, "industry": 1}]'
>>> 
>>> data = {
...     'user': 1,
...     'industry': 1
... }
>>> 
>>> response = c.post('http://localhost:8000/favorite_industries/', json.dumps(data), 'application/json')
>>> response.content
'{"id": 3, "user": 1, "industry": 1}'
>>> 
>>> response = c.get('http://localhost:8000/favorite_industries/')
>>> response.content
'[{"id": 1, "user": 1, "industry": 1}, {"id": 2, "user": 1, "industry": 1}, {"id": 3, "user": 1, "industry": 1}]'
>>> 
Run Code Online (Sandbox Code Playgroud)