我有这些示例数据库模型
class Book(models.Model):
name = CharField()
price = IntegerField()
class Author(models.Model):
name = CharField()
book = ForeignKey(Book, related_name='authors')
type = CharField(choices=('high','medium','low'))
class Random(models.Model):
book = Foreignkey(Book, related_name='randoms')
type = CharField(choices=('high','medium','low'))
rank = PositiveIntegerField()
数据库对象: -
b2 = Book('book2',30)
作者('author1',b1,'high')
作者('author4',b2,'low')
作者('author5',b2,'low')
作者('author6',b2,'low')
随机(b1,'高',1)
随机(b1,'中',2)
将会有一个Random
模型,其rank
表示特定类型图书的作者的正确数量。
例如,如果一本书有随机(书,'高',20)。那意味着必须有20位作者high
。如果有超过或少于20个作者,那么这是一个错误。
我想过滤那些有这种错误的Book
个对象。
这里b1
没有类型=低的作者,但是它有随机对象,其中'低'的等级是5.意味着必须有5个低类型的作者。 b1
有错误。
但这不是b2
如何过滤这些Book对象?
答案 0 :(得分:0)
您可以尝试过滤所有随机对象。然后使用for循环,您可以检查rank
和类型的作者数是否相等。这是一个代码[未经测试]。您可以使用count()。
all_random = Random.objects.all()
wrong_book=[]
for random in all_random:
if Author.objects.filter(book=random.book,type=random.type).count() != random.rank:
wrong_book.append(random.book)
result= set(wrong_book)
wrong_book是书籍对象的列表。
答案 1 :(得分:0)
最后,我想出了一种使用Django ORM的方法。
high_queryset = Books.objects.annotate(t=Case(When(authors__option='high',
then=Count('authors', distinct=True)), default=Value('0'),output_field=PositiveIntegerField(),),) \
.filter( Q(randoms__option='high') & ~Q(t=F('randoms__value')))
medium_queryset = Books.objects.annotate(t=Case(When(authors__option='medium',
then=Count('authors', distinct=True)), default=Value('0'),output_field=PositiveIntegerField(),),) \
.filter( Q(randoms__option='medium') & ~Q(t=F('randoms__value')))
low_queryset = Books.objects.annotate(t=Case(When(authors__option='low',
then=Count('authors', distinct=True)), default=Value('0'),output_field=PositiveIntegerField(),),) \
.filter( Q(randoms__option='low') & ~Q(t=F('randoms__value')))
final_queryset = (high_queryset | medium_queryset | low_queryset).distinct()