简体   繁体   English

Django:在组上过滤 ListView/在列表上迭代查询集

[英]Django: Filter ListView on Groups / Iterate queryset over list

Given a User can belong to more than one Group, I would like to ask how to filter on Groups in the below scenario.鉴于一个用户可以属于多个组,我想问一下如何在下面的场景中过滤组。

In Django I have a ListView showing a product list .在 Django 我有一个 ListView 显示产品列表

  • I have two groups: Company_1, Company_2.我有两个组:Company_1、Company_2。
  • I have 5 users: Worker_1, Worker_2, Worker_3, Worker_4, Inspector我有 5 个用户:Worker_1、Worker_2、Worker_3、Worker_4、Inspector

  • Worker_1, Worker_2, belongs to "Company_1" Worker_1,Worker_2,属于“Company_1”

  • Worker_3, Worker_4, belongs to "Company_2" Worker_3、Worker_4,属于“Company_2”
  • "Inspector" can inspect all Products from both Companies “检查员”可以检查两家公司的所有产品

Inspector has no superuser status or staff status, It should be seen as a normal user that belongs to two groups ['Company_1', 'Company_2'] Inspector 没有超级用户身份或员工身份,应该被视为属于两个组的普通用户 ['Company_1', 'Company_2']

Desired functionality:期望的功能:

Worker_1 register their own manufactured products in the application and can see a list of all products manufactured by Company_1. Worker_1 在应用程序中注册自己制造的产品,可以看到 Company_1 制造的所有产品的列表。

Inspector can see all products, from Company_1 and Company_2 Inspector 可以查看来自 Company_1 和 Company_2 的所有产品

In the below code attempts, however, Inspector cannot see any products.然而,在下面的代码尝试中,Inspector 看不到任何产品。

As Inspector belongs to ['Company_1', 'Company_2'] I need a way to check each Group membership in the list against the Group registered for a product.由于 Inspector 属于 ['Company_1', 'Company_2'] 我需要一种方法来根据为产品注册的组检查列表中的每个组成员身份。 Please note that below are simplified into two groups but in reality x number of groups and users.请注意,下面被简化为两个组,但实际上是 x 组和用户数。

in models.py在models.py中

from django.contrib.auth.models import User

class Product(models.Model):
    worker = models.ForeignKey(User, blank=True, on_delete=models.CASCADE)
    company = models.CharField(max_length=100, null=True, blank=True)

    def save(self, *args, **kwargs):
        self.company = list(self.worker.groups.all().values_list('name', flat=True))
        super(Product, self).save(*args, **kwargs)

within views.py在 views.py 中

class ProductListView(LoginRequiredMixin, ListView):
    model = Product
    template_name = 'product_list.html'

    def get_queryset(self):
        queryset = super(ProductListView, self).get_queryset()
        return queryset.filter(company__contains=list(self.request.user.groups.all().values_list('name', flat=True)))

Since your definition of the inspector is clear, we can then add some conditions in the get_queryset function.由于您对检查器的定义很明确,因此我们可以在 get_queryset 函数中添加一些条件。 Here is a pseudo-code:这是一个伪代码:

from django.contrib.auth.models import User, Group

class ProductListView(LoginRequiredMixin, ListView):
    model = Product
    template_name = 'product_list.html'

    def get_queryset(self):
        Company1 = Group.objects.get(name='Company1')
        Company2 = Group.objects.get(name='Company2')
        inspectors = User.objects.filter(groups=Company1 and groups=Company2).distinct() 
        if self.request.user in inspectors:
            return queryset.filter(company=Company1 or company=Company2).distinct().values_list('name', flat=True)))
        return queryset.filter(company__contains=list(self.request.user.groups.all().values_list('name', flat=True)))

I hope this helps, let me know if it's not working :)我希望这会有所帮助,如果它不起作用,请告诉我:)

I came up with a really ugly solution, but have to work for now.我想出了一个非常丑陋的解决方案,但现在必须工作。 Ideally, I need to figure out a dynamic way to express this.理想情况下,我需要找出一种动态的方式来表达这一点。 The real problem was to dynamically construct filters and combine those, especially with the manual construct of " | ".真正的问题是动态构造过滤器并将它们组合起来,特别是与“|”的手动构造。 There might exist a better solution, but for now I couldn't find it, or figure it out.可能存在更好的解决方案,但现在我找不到它,也找不到它。

class ProductListView(LoginRequiredMixin, ListView):
    model = Product
    template_name = 'product_list.html'

    def get_queryset(self):
        queryset = super(ProductListView, self).get_queryset()

        f = []
        for g in self.request.user.groups.all():
            f.append(f'{g}')

        d = len(f)

        if d == 0:
            g = queryset.filter(company__contains=f"")
        elif d == 1:
            g = queryset.filter(company__contains=f[0])
        elif d == 2:
            g = queryset.filter(company__contains=f[0]) | queryset.filter(company__contains=f[1])
        elif d == 3:
            g = queryset.filter(company__contains=f[0]) | queryset.filter(company__contains=f[1]) \
                | queryset.filter(company__contains=f[2])
        elif d == 4:
            g = queryset.filter(company__contains=f[0]) | queryset.filter(company__contains=f[1]) \
                | queryset.filter(company__contains=f[2]) | queryset.filter(company__contains=f[3])
        elif d == 5:
            g = queryset.filter(company__contains=f[0]) | queryset.filter(company__contains=f[1]) \
                | queryset.filter(company__contains=f[2]) | queryset.filter(company__contains=f[3]) \
                | queryset.filter(company__contains=f[4])
        elif d == 6:
            g = queryset.filter(company__contains=f[0]) | queryset.filter(company__contains=f[1]) \
                | queryset.filter(company__contains=f[2]) | queryset.filter(company__contains=f[3]) \
                | queryset.filter(company__contains=f[4]) | queryset.filter(company__contains=f[5])
        else:
            g = queryset

        return g

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM