0

我想为 ModelViewSet 使用路由器创建自定义或修改的 url。

当前情景:

/模型.py

class BlogPost(models.Model):
    title = models.CharField(max_length=300)
    description = models.TextField()
    slug = models.SlugField(max_length=300, unique=True)

/序列化程序.py

class BlogListSerializer(serializers.ModelSerializer):
    class Meta:
        model = BlogPost
        exclude = ('id',)

/views.py

class BlogViewSet(ModelViewSet):
    queryset = BlogPost.objects.all()
    serializer_class = BlogListSerializer

/urls.py

router = DefaultRouter()
router.register(r'blog', BlogViewSet, basename='blog')
urlpatterns = router.urls

现在,我可以访问以下网址:

列出https://localhost:8000/blog

检索https://localhost:8000/blog/1

如您所见,可以使用 pk 或 id 调用检索 url。但是我创建了一个名为 slug 的模型字段,它是独一无二的。我的问题是如何修改检索 url,以便我可以使用 slug 字段调用检索 url。例如:https://localhost:8000/blog/test-slug

注意:为什么我要使用 slug 创建一个 url?答:我想使用站点地图的网址。

4

3 回答 3

4

如果您的 api 需要通过查询 slug 字段(而不是字段)来返回结果,pk您可以使用 DRF 的lookup_fieldand lookup_url_kwarg

pkorid字段查找是默认查找并在 DRF 文档中提到。

https://www.django-rest-framework.org/api-guide/generic-views/

视图.py

class BlogViewSet(ModelViewSet):
    queryset = BlogPost.objects.all()
    serializer_class = BlogListSerializer
    lookup_field = 'slug'
    lookup_url_kwarg = 'slug'
于 2019-11-17T06:39:01.157 回答
0
# add a new url in your urlpatterns

urlpatterns = [
    path('blog/<slug:slug>/', views.Blogdetail.as_view(), name='blog_detail'),
]



# In views.py define a class Blogdetail or make changes in the existing class

class Blogdetail(ModelViewSet):
    queryset = BlogPost.objects.all()
    serializer_class = BlogDetailsSerializer


    def get_queryset(self):
        slug = self.request.query_params.get("slug", None)
        if  slug == None:
            queryset = self.queryset
        else:
            queryset = self.queryset.filter(slug = slug)
        return queryset
于 2019-11-17T06:27:26.157 回答
0
class Blogdetail(generics.RetrieveAPIView):
    queryset = BlogPost.objects.all()
    serializer_class = BlogDetailsSerializer

    def get_object(self):
        slug = self.kwargs["slug"]
        obj = get_object_or_404(BlogPost, slug=slug)
        return obj

class BlogUrlHyperlinkedIdentityField(serializers.HyperlinkedIdentityField)

        def get_url(self, obj, view_name, request, format):
            kwargs = {
                "slug": obj.slug
            }
            return reverse(view_name, kwargs=kwargs, request=request, format=format)

class BlogListSerializer(serializers.ModelSerializer):
    url = BlogUrlHyperlinkedIdentityField("blog_detail")
    class Meta:
        model = BlogPost
       fields = [
            "url",.....]

还要加上网址

path('blog/<slug:slug>/', views.Blogdetail.as_view(), name='blog_detail'),
于 2019-11-17T07:35:00.490 回答