Django:检查关联对象及其是否包含数据

19 投票
4 回答
27660 浏览
提问于 2025-04-18 03:04

举个例子,我在一个汽车管理系统(网页)里有两个模型:

    class Brand(models.Model):
        brand_name= models.CharField(max_length=100, null=False)

    class Cars(models.Model):
        car_model= models.CharField(max_length=100, null=False)
        car_production_year= models.CharField(max_length=100, null=False)
        car_brand= models.ForeignKey(Brand, null=True, blank=True, default = None)

现在,我想从汽车系统中删除一个品牌的数据。我该如何检查这个品牌是否在其他模型中被使用,或者这个外键是否包含任何数据(因为我在汽车模型中允许 car_brand 为空)呢?

附注:我使用了这个函数:

self.model._meta.get_all_related_objects():

我在品牌模型类中得到了任何相关的对象。但是,我不知道如何判断这个相关对象是否包含任何数据。

4 个回答

1

在编程中,有时候我们需要处理一些数据,比如从一个地方获取数据,然后把它放到另一个地方。这就像是把水从一个杯子倒到另一个杯子一样。

当我们在写代码的时候,可能会遇到一些问题,比如数据的格式不对,或者我们想要的数据没有被正确获取。这就像是你想喝水,但杯子里却是果汁,这样你就不能直接喝了。

为了避免这些问题,我们需要检查数据的来源和格式,确保它们是正确的。这样才能顺利地把数据从一个地方移动到另一个地方,而不会出错。

总之,处理数据就像是搬家一样,我们需要仔细检查每个箱子里的东西,确保它们都在正确的位置,这样才能顺利完成搬家。

cars_with_brands = Car.objects.filter(car_brand__isnull = False)
if cars_with_brands.count() == 0:
    # you can delete Brand Model
else:
   cars_with_brands.delete()
   # you can delete Brand Model
2

我觉得最简单的方法就是这样:

# brand is an instance of Brand

if not brand.cars_set.all():
    # delete
else:
    # do something else

Django文档对外键的内容讲得非常详细。

10

这个问题中,对于我的代码来说,这种方法更快:

for b in Brand.objects.filter(cars__isnull=True):
    # delete

如果你有这些ID(就像我这种情况),我用了这个方法(比cars_set快60%):

for brand_id in brand_id_set:
    if Brand.objects.filter(id=brand_id).filter(cars__isnull=True):
        # delete

我使用的是Django 1.11版本

21

使用 exists()。它就是为了处理这种情况而设计的:

for brand in Brand.objects.all():
    if not brand.cars_set.all().exists():
        # delete

而且,它的速度几乎总是比其他检查方法快,因为它在数据库层面上工作的方式。你可以在 文档 中查看 exists() 的具体行为。

撰写回答