Django休息框架,更改ForeignKey

时间:2018-05-19 16:52:29

标签: django django-rest-framework

我和DRF战斗的时间太长所以现在我必须提出问题..如何将ForeignKey改为另一个?我有用户配置文件和状态模型的关系。

models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    ldap_uid = models.CharField(max_length=100, blank=True, null=True, default=None)
    redmine_id = models.IntegerField(blank=True, null=True, default=None)
    status = models.ForeignKey(Status, models.SET_NULL, blank=False, null=True, default=DEFAULT_STATUS_ID)
    location = models.ForeignKey(Location, models.SET_NULL, blank=False, null=True, default=DEFAULT_LOCATION_ID)
    online = models.BooleanField(default=False)


class SelectValuesModel(models.Model):
    name = models.CharField(max_length=100)
    display_name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

    class Meta:
        abstract = True


class Status(SelectValuesModel):
    pass


class Location(SelectValuesModel):
    pass

将个人资料状态更改为另一个的好方法是什么?我正在尝试这样的事情而没有成功

views.py

class UserStatusView(viewsets.ViewSet):
    def partial_update(self, request, pk=None):
        user = User.objects.get(pk=pk)
        user_profile = user.profile
        new_stauts = Status.objects.get(request.data.status)
        serialized_data = ProfileSerializer(user_profile)
        if(serialized_data.is_valid()):
            serialized_data.save(status=new_stauts)
        return Response(serialized_data.errors)

尝试通过PATCH发送新ID。我正在尝试寻找解决方案但在这里也没有成功。它怎么样好?制作另一条路线来更新个人资料状态或者制作类似profile / 1 / update_status / 2的内容?现在我的路由看起来像:

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'redmine', views.RedmineCurrentTaskView, base_name='redmine')
router.register(r'parameters', views.ParametersView, base_name='parameters')
router.register(r'update_status', views.UserStatusView, base_name='update_status')
router.register(r'debug', views.DebugStatus, base_name='debug')

urlpatterns = [
    path('', views.index, name='index'),
    path('api/', include(router.urls))
]

和serializers.py

class SelectValuesSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ('pk', 'name', 'display_name')


class LocationSerializer(SelectValuesSerializer):
    class Meta(SelectValuesSerializer.Meta):
        model = Location


class StatusSerializer(SelectValuesSerializer):
    class Meta(SelectValuesSerializer.Meta):
        model = Status


class ProfileSerializer(serializers.ModelSerializer):
    status = StatusSerializer()
    location = LocationSerializer()

    class Meta:
        model = Profile
        fields = ('status', 'location', 'online', 'redmine_id')


class UserSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer(read_only=True)

    class Meta:
        model = User
        fields = ('pk', 'first_name', 'profile')
        read_only_fields = ('first_name',)

1 个答案:

答案 0 :(得分:3)

只需将request.data传递给带有partial=True参数的序列化程序:

class UserStatusView(viewsets.ViewSet):
    def partial_update(self, request, pk=None):
        user = User.objects.get(pk=pk)
        user_profile = user.profile
        serialized_data = ProfileSerializer(user_profile, data=request.data, partial=True)
        if serialized_data.is_valid():
            serialized_data.save()
            return Response(serialized_data.data)
        return Response(serialized_data.errors)

您需要提供status_id和请求正文,如下所示:

{"status": 1}

<强> UPD

要将状态作为ID传递,请将序列化程序更改为:

class ProfileSerializer(serializers.ModelSerializer):
    location = LocationSerializer()

    class Meta:
        model = Profile
        fields = ('status', 'location', 'online', 'redmine_id')

    def to_representation(self, instance):
        self.fields['status'] = StatusSerializer()
        return super(ProfileSerializer, self).to_representation(instance)

这允许发布status_id,但使用您的API获取状态详细信息。