Django-Rest-Framework updating a foreign key BY Id

后端 未结 2 1849
野性不改
野性不改 2020-12-31 12:33

I am using django-rest-framework to build out the back end. I have the list running fine, but (using the django-rest-framework admin screen) I cannot create an object by ju

相关标签:
2条回答
  • 2020-12-31 12:57

    This will do it. But I think the django-rest-framework should provide this plumbing for me, so please follow up with any better answers

    class FavoriteIndustriesViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
        paginate_by = 1
        queryset = myModels\
            .FavoriteIndustry\
            .objects\
            .select_related()
        print 'SQL::FavoriteIndustriesViewSet: ' + str(queryset.query)
        serializer_class = mySerializers.FavoriteIndustrySerializer
    
        def create(self, request):
            print(request.DATA)
            user_id = request.DATA['user_id']
            industry_id = request.DATA['industry_id']
            favorite = myModels.FavoriteIndustry(user_id=user_id, industry_id=industry_id)
            favorite.save()
            responseData = {
                'user_id': user_id
                , 'industry_id': industry_id
                , 'message': 'FavoriteIndustry saved.'
            }
            return Response(responseData)
    
    0 讨论(0)
  • 2020-12-31 12:58

    I have created a simplified mock up of your application.

    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)
    

    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
    

    serializers.py:

    from rest_framework import serializers
    from models import FavoriteIndustry, Industry
    
    class FavoriteIndustrySerializer(serializers.HyperlinkedModelSerializer):
        class Meta:
            model = FavoriteIndustry
            fields = ('id', 'user', 'industry')
    

    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'),
    )
    

    And here are a few tests:

    >>> 
    >>> 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/"}]'
    >>> 
    

    Django REST Framework expects user and industry fields as URLs rather than ids since you are using HyperlinkedModelSerializer.


    Using IDs

    In case you need to use object ids instead of URLs, use ModelSerializer instead of HyperlinkedModelSerializer and pass ids to user and industry:

    serializers.py:

    from rest_framework import serializers
    from models import FavoriteIndustry, Industry
    
    class FavoriteIndustrySerializer(serializers.ModelSerializer):
        class Meta:
            model = FavoriteIndustry
            fields = ('id', 'user', 'industry')
    

    And tests:

    >>> 
    >>> 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}]'
    >>> 
    
    0 讨论(0)
提交回复
热议问题