通过 Django REST POST 更新模型实例
Posted
技术标签:
【中文标题】通过 Django REST POST 更新模型实例【英文标题】:Update Model Instance via Django REST POST 【发布时间】:2018-04-26 15:04:15 【问题描述】:我有一个模型“分配”,我希望能够通过 api 进行更新。
按 cmets 更新
urls.py
router = routers.DefaultRouter()
router.register(r'assignments', views.AssignmentList, base_name='Assignments')
urlpatterns = [
url(r'^api/v1/', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]
serializers.py
class AssignmentSerializer(serializers.ModelSerializer):
class Meta:
model = Assignment
fields = (
'id', 'company', 'farm', 'sensor', 'name', 'location', 'notes', 'units', 'max_height', 'frequency',
'interval', 'max_threshold', 'min_threshold', 'notify', 'last_alert_time', 'last_alert_water_level')
views.py
class AssignmentList(viewsets.ModelViewSet):
serializer_class = AssignmentSerializer
pagination_class = None
def get_queryset(self):
queryset = Assignment.objects.all()
company_id = self.request.query_params.get('company_id', None)
sensor_id = self.request.query_params.get('sensor_id', None)
if company_id is not None:
queryset = Assignment.objects.filter(company_id=company_id)
if sensor_id is not None:
queryset = Assignment.objects.filter(sensor_id=sensor_id)
return queryset
目前,我的视图允许基于两个字段“company_id”和“sensor_id”轻松过滤。这允许轻松访问 json 中的数据。不幸的是,即使使用内置的 API 表单,我也不知道如何回帖。我希望能够过滤到单个实例并编辑单个字段,我们现在说“assignment.name”。
我的理解是……
ModelViewSet 类提供的操作是 .list()、.retrieve()、.create()、.update()、.partial_update() 和 .destroy()。 (DRF Docs)
那么我需要做些什么来利用它们通过 url 编辑模型实例?或者老实说只是编辑一个时期。我一直在尝试不同的 Mixins、视图(UpdateAPIView、RetrieveUpdateAPIView 等),尤其是这个问题Stack Overflow: Django Rest Framework update field。
【问题讨论】:
你不需要做任何事情。 ViewSet 已经完成了支持这一点所需的一切。 那么我该如何使用它呢?内置表单将无法验证,因为它缺少外键“company_id”、“farm_id”和“sensor_id”。为什么它缺少这些完全是另一个问题。 【参考方案1】:为什么您缺少所需的外键字段是完全的问题。
原因大概是你的字段叫company
、farm
和sensor
,而不是company_id
等。因为底层数据库字段是叫company_id
等等, DRF 将它们检测为模型上的只读属性,因此允许您在字段元组中指定这些名称而不会显示错误,但不会在可浏览的 API 中显示该字段。更改 fields
元组以包含 Django 字段的实际名称。
还要注意,由于您使用的是 HyperlinkedModelSerializer,因此 DRF 需要为这些相关模型提供链接的 ViewSet。如果您没有定义这些,请将其更改为基本的 ModelSerializer。
【讨论】:
感谢您的关注。 API 之前对所有字段进行了序列化,但表单中缺少这些字段。现在,这些字段使用充满“公司/农场/传感器对象”的选择进行渲染。所以它不是真的可用(没有区分对象),但选择它们将允许表单发布。我将如何选择要编辑的实例? 在这些模型上定义一个__str__
方法(或者 __unicode__
,如果您仍在使用 Python 2.7) - 这与管理站点的原理相同。
您能详细说明一下吗?也许在上面的答案中添加一个例子?我只是不确定您所说的“在 那些 模型上定义 __str__
方法”是什么意思。我只是想编辑模型实例的字段。
为了让 Company 的相关实例显示有用的表示,您需要在该 Company 模型上返回该表示的方法 - 对于 Sensor 和 Farm 也是如此。见the docs。
非常感谢您的提示!我给每个对象一个 str 来区分它。我以前在做一些非常糟糕的 jinja 和变通方法来解决这个问题。所以现在我已经完成了 .list()、.create() 操作。如何使用 .retrieve()、.update()、.partial_update() 和 .destroy()?以上是关于通过 Django REST POST 更新模型实例的主要内容,如果未能解决你的问题,请参考以下文章
使用 Django Rest Framework 序列化程序更新现有模型
Django Rest Framework:POST时自动填充模型的字段?
如何在单个帖子中更新多个实例 - django rest 框架