Django:在组上过滤 ListView/在列表上迭代查询集
Django: Filter ListView on Groups / Iterate queryset over list
鉴于一个用户可以属于多个组,我想问一下如何在下面的场景中过滤组。
在 Django 中,我有一个 ListView 显示 产品列表。
- 我有两个组:Company_1、Company_2。
我有 5 个用户:Worker_1、Worker_2、Worker_3、Worker_4、Inspector
Worker_1,Worker_2,属于"Company_1"
- Worker_3,Worker_4,属于"Company_2"
- "Inspector" 可以检查两家公司的所有产品
Inspector没有超级用户身份和staff身份,应该看成属于两个组的普通用户['Company_1', 'Company_2']
所需功能:
Worker_1在应用中注册自己生产的产品,可以看到Company_1.
生产的所有产品列表
检查员可以查看所有产品,从 Company_1 到 Company_2
但是,在下面的代码尝试中,Inspector 看不到任何产品。
由于 Inspector 属于 ['Company_1','Company_2'],我需要一种方法来检查列表中的每个组成员与为产品注册的组。
请注意,下面被简化为两组,但实际上 x 组和用户的数量。
在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)
在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)))
既然你对inspector的定义很明确,那我们就可以在get_queryset函数中添加一些条件。这是一个伪代码:
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)))
希望对您有所帮助,如果它不起作用请告诉我:)
我想出了一个非常丑陋的解决方案,但现在必须工作。理想情况下,我需要找出一种动态的方式来表达这一点。真正的问题是动态构造过滤器并将它们组合起来,尤其是与“|”的手动构造。可能存在更好的解决方案,但目前我找不到,也没有弄清楚。
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
鉴于一个用户可以属于多个组,我想问一下如何在下面的场景中过滤组。
在 Django 中,我有一个 ListView 显示 产品列表。
- 我有两个组:Company_1、Company_2。
我有 5 个用户:Worker_1、Worker_2、Worker_3、Worker_4、Inspector
Worker_1,Worker_2,属于"Company_1"
- Worker_3,Worker_4,属于"Company_2"
- "Inspector" 可以检查两家公司的所有产品
Inspector没有超级用户身份和staff身份,应该看成属于两个组的普通用户['Company_1', 'Company_2']
所需功能:
Worker_1在应用中注册自己生产的产品,可以看到Company_1.
生产的所有产品列表检查员可以查看所有产品,从 Company_1 到 Company_2
但是,在下面的代码尝试中,Inspector 看不到任何产品。
由于 Inspector 属于 ['Company_1','Company_2'],我需要一种方法来检查列表中的每个组成员与为产品注册的组。 请注意,下面被简化为两组,但实际上 x 组和用户的数量。
在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)
在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)))
既然你对inspector的定义很明确,那我们就可以在get_queryset函数中添加一些条件。这是一个伪代码:
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)))
希望对您有所帮助,如果它不起作用请告诉我:)
我想出了一个非常丑陋的解决方案,但现在必须工作。理想情况下,我需要找出一种动态的方式来表达这一点。真正的问题是动态构造过滤器并将它们组合起来,尤其是与“|”的手动构造。可能存在更好的解决方案,但目前我找不到,也没有弄清楚。
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