首页 > 解决方案 > 在 django 的 url 中发送参数

问题描述

我有 2 个模型:

class Tag(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name


class Question(models.Model):
     name = models.CharField(max_length=255)
     Tag_name = models.ManyToManyField(Tag)

     def __str__(self):
        return self.name

视图.py

class QuestionList(APIView):

def get(self, request, tag_id):

    res = Question.objects.filter(Tag_name=tag_id).prefetch_related('Tag_name').order_by('name')[:10]
    print(res)
    serializer = QuestionSerializers(res, many=True)
    data = {}
    return Response(serializer.data)
    # return Response(data)

网址.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('tag=<int:tag_id>/', views.QuestionList.as_view()) //this needs to be edited
]

url.py 文件中发送 id 和 name 参数并获取数据的路径是什么

http://127.0.0.1:8000?tag=4&order_by=name

所以我收到所有关于标签 4 的问题并按名称排序?

标签: pythondjangodjango-modelsdjango-rest-frameworkdjango-forms

解决方案


查询字符串[wiki]不是路径的一部分。这些参数可以在request.GET对象中获取,对象是类字典对象。

因此,您的路径应如下所示:

path('/', views.QuestionListView.as_view()),

在您的QuestionListView中,您可以过滤这些参数:

class QuestionListView(ListAPIView):
    model = Question
    serializers = QuestionSerializers

    def get_queryset(self, *args, **kwargs):
        queryset = super().get_queryset(*args, **kwargs)
        if 'tag' in self.request.GET:
            queryset = queryset.filter(
                Tag_name=self.request.GET['tag']
            )
        if 'order_by' in self.request.GET:
            queryset = queryset.order_by(self.request.GET['order_by'])
        return queryset

    # …

话虽这么说,以上将需要额外的脚手架。在这里,您允许用户在.order_by(..). 黑客可以利用这一点,例如通过对相关数据的元素进行排序,从而对某些字段进行二进制搜索。

可能值得一看django-filter[GitHub],您可以在其中根据可以过滤的元素等进行定义。它还将封装过滤,从而方便在不同的视图中使用它。

注意:通常 Django 模型中的字段名称是用 snake_case 编写的而不是PerlCase,所以它应该是:tags而不是Tag_name. 这是因为 aManyToManyField指的是零个、一个或多个标签,而且它指的是标签对象,而不是标签的名称。

 

注意:与其从头开始实现视图,不如看看 已经可以实现大量样板代码的ListAPIView类 [drf-doc]


推荐阅读