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