Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django rest框架,更改ForeignKey_Django_Django Rest Framework - Fatal编程技术网

Django rest框架,更改ForeignKey

Django rest框架,更改ForeignKey,django,django-rest-framework,Django,Django Rest Framework,我和DRF斗争的时间太长了,所以现在我必须问一个问题。。如何把外键换成另一个?我有用户配置文件和与状态模型的关系 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) r

我和DRF斗争的时间太长了,所以现在我必须问一个问题。。如何把外键换成另一个?我有用户配置文件和与状态模型的关系

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)
并尝试通过补丁发送新id。我试图找到解决办法,但也没有成功。这有什么好处?是否为更新配置文件状态创建另一个路由?或者做一些像profile/1/update\u 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',)

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

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": 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)

这允许发布状态id,但可以通过API获取状态详细信息。

我将其绑定并始终获取错误:{“状态”:{“非字段错误”:[“无效数据。需要一个字典,但得到int.”]}}我想您应该在serializer中设置
status=StatusSerializer()
?您只需将其添加到
to_representation
方法中,即可仅显示GET请求的状态详细信息。@Sierran我已更新了答案:)您需要将
添加到_representation
并删除
status=StatusSerializer()
。哦,我的天哪!它起作用了!非常感谢。但是为了将来。。这是个好办法吗?我在DRF文档中找不到。创建路由的最佳实践是什么?Thanx!我知道这是个蹩脚的问题。。但是你能在我的例子中给我解释一下吗?在文档中,我100%了解如何使用它,但在我的示例中?在我的问题中,我不理解有to_表示和没有to_表示的区别,status=StatusSerializer()和self.fields['status']=StatusSerializer()之间的区别是什么。为什么我们要用super?