django 如何在模型有OneToOneField时创建ModelViewset?

e4eetjau  于 2022-12-05  发布在  Go
关注(0)|答案(1)|浏览(143)

我们的想法是建立这样一个模型:

class Object(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=256)

    def __str__(self):
        return self.name

然后创建一个序列化程序和一个与之相关ModelViewSet
问题是ModelViewSet必须返回一个queryset,但由于一对一的关系,我希望使用单个对象。
我该如何继续?

qyswt5oh

qyswt5oh1#

如文档中所述:
ModelViewSet类继承自GenericAPIView,并通过混合各种mixin类的行为来实现各种操作。
这意味着ModelViewSet也会处理返回特定Object的情况。如果你想要一个比实现的更复杂的行为,你甚至可以覆盖def get_object(self)(参见SO question)。
但是,为了确保只返回一个Object,我建议您使用一个字段作为唯一主键,您可以在插入时填充该字段(手动或自动),然后将其用作lookup_field
下面,我假设您的User模型中也已经有了一个__str__(self)函数。
然后,您的Object模型将变为:

class Object(models.Model):
    id = models.BigAutoField(primary_key=True)  # or another unique primary_key field 
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=256)

    def __str__(self):
        return f"{self.name} ({self.id})"

您的序列化程序将是:

class ObjectSerializer(serializers.ModelSerializer):
    class Meta:
        model = Object
        fields = ("id", "name", "user")

    id = serializers.CharField(required=True)

您的ModelViewSet将类似于:

class ObjectViewSet(viewsets.ModelViewSet):
    http_method_names = ["get"]
    # parser_classes = [JSONParser] # Replace with your parser class
    queryset = Object.objects.all()
    serializer_class = ObjectSerializer
    lookup_field = "id"

最后,要使整个过程正常工作,还必须在urlpatterns中注册ModelViewSet
我使用显式地将我的ViewSet类绑定到一组具体的视图中,但这更多的是个人的选择,所以这取决于你。你可以查看相应的documentation以获得更多信息。

urlpatterns = [
    ...
    path(
        r"objects/<str:id>",
        ObjectViewSet.as_view({"get": "retrieve"}),
    ),
    ...
]

在所有这些情况下,对<BASE_URL>/objects/<YOUR_OBJECT_ID>的请求应该只返回一个Object结果。

相关问题