【问题标题】:send parameters in url in django在 django 的 url 中发送参数
【发布时间】:2020-05-13 19:10:56
【问题描述】:

我有 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

views.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)

urls.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 并按名称排序的问题?

【问题讨论】:

  • 查询字符串不是路径的一部分。
  • 好的,我该如何实现呢?
  • 有人可以发给我views.py 吗?
  • 请向我们展示您的意见。py
  • 刚刚添加了views.py文件

标签: python django django-models django-rest-framework django-forms


【解决方案1】:

query string [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,所以应该是:@ 987654330@ 而不是 Tag_name。这是因为ManyToManyField 指的是零个、一个或多个标签,而且它指的是标签objects,而不是标签的名称。

 

注意:与其从头实现视图,不如看一看 ListAPIView class [drf-doc] 已经可以实现很多样板代码

【讨论】:

  • 有趣的警告。我希望 Django 有一种开箱即用的方法来修复这个注入漏洞。它一定是一个足够受欢迎的任务
  • @DeepSpace: 问题是你无法解决这个问题,因为用户可能想要对.order_by('user__password') 进行排序(请注意,这将使用 hash,但是尽管如此,公开密码哈希仍然不是一个好主意)。
  • 'super' 对象没有属性 'get_queryset' 是我遇到的错误
  • @code_freak4:在一个简单的ApiView中,确实没有get_queryset。你用了ListAPIView吗?
  • 你的意思是我使用 ListAPIView 而不是 get_queryset ?
【解决方案2】:

如果你想通过 Django 使用这个 Url 发送多个 Url 参数:

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

使用 urls.py 中的路径试试这个:

path('tag=<int:tag_id>/order_by=<str:name>', views.QuestionList.as_view()) 

你有一个很好的例子hereDjango docs,或者找到我的博客,里面有关于 Django 的文章。

【讨论】:

    猜你喜欢
    • 2016-08-07
    • 1970-01-01
    • 2021-04-21
    • 2015-12-03
    • 1970-01-01
    • 2019-08-11
    • 2019-07-20
    • 2017-10-31
    • 2017-02-13
    相关资源
    最近更新 更多