通过 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】:

为什么您缺少所需的外键字段是完全的问题。

原因大概是你的字段叫companyfarmsensor,而不是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 框架

Django REST Framework 更新外键

如何使用 Django Rest Framework 创建多个模型实例?

Django Rest API,如何为 2 个模型条目创建 post api,并具有与模型关联的外键