Django - 按用户过滤

Posted

技术标签:

【中文标题】Django - 按用户过滤【英文标题】:Django - filtering by user 【发布时间】:2018-05-10 03:11:40 【问题描述】:

我想在他们的“帐户”页面中呈现属于司机的 Route 模型中的数据 - 因此显示他们迄今为止保存在数据库中的 leave_from、目的地等数据。

模型.py:

class Driver(models.Model):
    user = models.OneToOneField(User, default=1)
    first_name = models.CharField(max_length=120, blank=True, null=True)
    last_name = models.CharField(max_length=120, blank=True, null=True)
    tel = models.CharField(max_length=120, blank=True, null=True)
    slug = models.SlugField(max_length=120, unique=True)
    timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
    updated = models.DateTimeField(auto_now_add=False, auto_now=True)

    def __str__(self):
        return self.user.username

    def get_absolute_url(self):
        return reverse("account", kwargs="slug": self.slug)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.first_name)
        super(Driver, self).save(*args, **kwargs)

class Route(models.Model):
    leave_from = models.CharField(max_length=120, blank=True, null=True)
    destination = models.CharField(max_length=120, blank=True, null=True)
    date = models.DateField(auto_now_add=False, auto_now=False)
    time = models.TimeField(auto_now_add=False, auto_now=False)
    driver = models.ForeignKey(Driver, on_delete=models.CASCADE)

    def __str__(self):
        return self.leave_from

我玩过各种查询集,下面是最接近那里的(我认为......我是编码和 Django 的新手)。

Views.py:

def route(request, slug):
    routedetails = Driver.objects.filter(route=request.user.driver.route_set.all())
    context = 
        "routedetails": routedetails,
        
    return render(request, "route.html", context)

这样我就可以让用户在 Route 中为该 Driver 显示相同数量的数据实例。

模板:

    % for route in routedetails %
        <p> route.user </p>
    % endfor %

我尝试了所有不同的变体,但我觉得这让我最接近,因为它至少返回用户的次数与此用户的 Route 中的数据相同。在这种情况下,Route 中保存了 2 个路由,因此用户名被返回两次。我在其他用户上测试过,它总是匹配的。

我到处寻找,这是我所能得到的,非常感谢任何帮助。

【问题讨论】:

【参考方案1】:

如果你想要Route的详细信息最好直接查询Route模型:

routedetails = Route.objects.filter(driver__user=request.user)

然后您可以遍历模板中的 Route 对象:

% for route in routedetails %
    <p> route.leave_from </p>
    <p> route.destination </p>
    ...
% endfor %

【讨论】:

【参考方案2】:

Pocket Kings 的解决方案很棒,应该被接受。这是一个示例,如果您想显示多个驱动程序的路线(管理页面?)以避免 N+1 查询。这会预取与驱动程序关联的所有路由,并为每个驱动程序添加一个属性路由及其特定路由,以便以后消除不需要的 SQL 查询。

from django.db.models import Prefetch

drivers = Driver.objects.all()
queryset = drivers.prefetch_related(Prefetch('route_set', queryset=Route.objects.filter(driver_id__in=drivers), to_attr='routes'))

模板

% for driver in drivers %
    % for route in driver.routes %
        <p> route.leave_from </p>
        <p> route.destination </p>
        ...
    % endfor %
% endfor %

【讨论】:

【参考方案3】:

要登录司机的路线,最简单的方法是。

views.py

routes = request.user.driver.route_set.all()

模板

% for route in routes %
     route.leave_from 
     route.destination 
% endfor %

【讨论】:

以上是关于Django - 按用户过滤的主要内容,如果未能解决你的问题,请参考以下文章

Django,按用户全名过滤 Q 对象

Django - 按用户过滤

Django按用户组过滤外键关系

在 Django admin 中,如何按组过滤用户?

按用户角色和 id 过滤的 Django 自定义权限

Django 仅使用 Sqlite 按距离过滤(无 GeoDjango、PostGres、MySQL、GIS)