【问题标题】:Query Database Table Without Using Foreign Key Django Postgresql不使用外键 Django Postgresql 查询数据库表
【发布时间】:2018-04-13 22:39:12
【问题描述】:

我正在尝试查询一个有许多同名记录的表,这是故意的。在我的示例中,我使用的是汽车品牌,不幸的是我已经排除了使用外键的可能性。很长的故事。无论如何,我已经能够确定我可以使用 ModelChoiceField 并使用 distinct 命令来查询表,因为我正在使用 Postgresql,如下所示:

class Vehicle(forms.Form):

    dropdown = forms.ModelChoiceField(queryset=Car.objects.none())

    def __init__(self, *args, **kwargs):
        super(Vehicle, self).__init__(*args, **kwargs)
        self.fields['dropdown'].empty_label = ''     
        qs = Car.objects.distinct('vehicle_make')  

上面的代码做了我需要的与下拉菜单相关的事情,它将 ModelChoiceField 限制为汽车的 vehicle_make 的唯一值。

挑战是当我尝试在我的模板中显示带有该 vehicle_make 的所有记录时。我试图做一个详细视图,但它只向我展示了那条记录。这是有道理的,因为详细视图仅适用于该记录,但我试图弄清楚如何查询表以向我显示带有该 vehicle_make 的所有记录。我也探索了 ChoiceField ,但似乎也无法让它发挥作用。我在模板中尝试了以下代码的几种变体,但似乎没有任何效果。

{% for vehicle_make in car.queryset %}
   {{ vehicle_make }}
{% endfor %}

我的模型如下:

Car(models.Model):
    vehicle_make = models.Charfield(max_length=264,unique=False)

    def __str__(self):
        return self.vehicle_make

提前感谢您的意见和建议。

【问题讨论】:

  • 你也可以发布你的模型吗?
  • souldeux 有帮助吗?

标签: django python-3.x django-forms django-templates django-views


【解决方案1】:

您可以使用Car.objects.filter(vehicle_make = 'foo') 查询具有vehicle_make 给定值的所有Car 对象。例如,ListView 将列出所有汽车:

from django.views.generic.list import ListView
from .models import Car

class CarListView(ListView):
    context_object_name = "car_list"
    queryset = Car.objects.all()

而此视图将列出所有制造商'foo' 的汽车:

class FooCarListView(ListView):
    context_object_name = "car_list"
    queryset = Car.objects.filter(vehicle_make = 'foo')

一种更“动态”的简单方法是在 url 中查找搜索查询,无论是作为关键字参数还是作为查询字符串。您可以使用现有的表单来创建这样的 URL,然后在视图中解析它。例如,此视图将查找带有 ?search=bar 的 URL:

class SearchableCarListView(ListView):
    context_object_name = "car_list"
    def get_queryset(self):
        search_term = self.request.GET.get('search', None)
        if search_term is not None:
            return Car.objects.filter(vehicle_make = search_term)
        return Car.objects.all()

使用icontainsiexact 查找,甚至使用Django 的full text search,可能会更好地满足您的用例。

在这些视图的模板中,您可以访问查询集中的所有 Car 对象,如下所示:

{% for car in car_list %}
    {{car}}
{% endfor %} 

我希望我已经理解并解决了您的问题。我不能 100% 确定您现在是如何使用表单的,所以如果我忽略了其中的任何内容,请告诉我。


在我们在 cmets 中讨论之后,我认为您的表单过于复杂,并且我认为您的查找可能没有按照您的意愿进行。

我们将获得所有不同 vehicle_make 值的 ValuesQuerySet

qs = Car.objects.values('vehicle_make').distinct()

(参见:Select DISTINCT individual columns in django?

这会返回一个ValuesQuerySet,如下所示:

<QuerySet [{'vehicle_make': 'vehicle_make_1'}, {'vehicle_make': 'vehicle_make_2'}...]

vehicle_make_1vehicle_make_2 等是您的独特价值观。

我们可以将这个查询集qs 赋予我们的模板并构造一个select 元素。我们还可以先将其简化为值列表,以便在模板中更容易使用:

values_list = [ c['vehicle_make'] for c in qs.all() ]

将该值传递给我们的模板并使用它来制作我们的select 元素:

<select name='search'>
    {% for vehicle_make in values_list %}
    <option value = {{vehicle_make}} > {{vehicle_make}} </option>
    {% endfor %}
</select>

从这里你有几个选择。在我看来,最简单的方法是在使用GET 方法的表单中使用这个select 元素来构造我们之前讨论过的搜索URL。查看此问题的第一个答案以获取更多信息:<form method="link" > or <a>? What's the difference? 该问题的第一个答案中有一个代码 sn-p,可以很容易地调整以使用您新创建的 @ 创建基于 GET 的搜索表单987654353@元素。

【讨论】:

  • 感谢您的回复。我正在使用表单来尝试获取要提供给 ListView 的值。在这种情况下,我应该使用您建议的 URL 方法吗?您表示我可以使用相同的表单,但我还需要创建一个新 URL 吗?
  • 您可以使用在表单中选择的值来构造一个我们讨论过的 URL。然后您可以将您的用户重定向到该 URL,或使用该 URL 从您的服务器获取数据以填充您现有的模板。第二种方法将涉及 AJAX 请求。
  • 感谢您的帮助。我测试了上面的所有代码,是的,我最终试图做一些动态的事情,在下拉框中获取 vehicle_make,然后尝试使用它们的详细信息搜索记录。我已经看到该列表很有帮助,但我最终试图从一个表中获取所有记录及其所有属性,基本上是用户在下拉列表中选择值后详细视图中的所有记录。我是 Django 新手...我只需将搜索值添加到 URL 中即可获取记录的详细视图?
  • 花点时间了解一下 ListView 和 DetailView 之间的区别:docs.djangoproject.com/en/1.11/ref/class-based-views/…。这些视图将返回您告诉它们返回的东西;我给出的示例显示了一种过滤 ListView 返回的查询集的方法。我希望这会有所帮助。
  • souldeux 再次感谢您的帮助。我对观点之间的差异感到非常满意。我遇到的问题是我无法获得下拉表单来限制我的选择。您建议的 ListView 方法似乎给了我所有的记录,除非我在过滤器中硬编码一个值。我正在尝试执行您建议的动态方法,只需要处理 URL 部分。
猜你喜欢
  • 2014-06-17
  • 2014-11-19
  • 1970-01-01
  • 2022-10-25
  • 2021-01-15
  • 1970-01-01
  • 1970-01-01
  • 2020-01-30
  • 2011-02-01
相关资源
最近更新 更多