姜戈 subquery/prefech_related
Django subquery/prefech_related
比如我有模型:
class Location(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
...
class ControlPoint(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
location = models.ForeignKey(Location, related_name='+', on_delete=models.CASCADE, verbose_name='Локация')
order = models.IntegerField(default=0)
route = models.ForeignKey('Route', related_name='control_points', on_delete=models.CASCADE)
...
class Route(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
@property
def get_departure(self):
return self.control_points.get(order=0)
@property
def get_arrival(self):
return self.control_points.order_by('-order')[0]
def clear_control_points(self):
self.control_points.all().delete()
class Trip(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
route = models.OneToOneField(Route, related_name='trips', null=True, on_delete=models.SET_NULL)
user = models.ForeignKey(User, related_name='trips', on_delete=models.CASCADE)
...
解决
根据以下cengineer的回答(非常感谢他):
Trip.objects.filter(route_id__in=Subquery(ControlPoint.objects.filter(location_id=<location_id>).values('route_id')))
如果你知道如何以不同的方式解决这个问题,我会很高兴看到你的例子。
是的,您可以使用子查询解决此问题。在你的情况下应该是这样的
Trip.objects.filter(route_id__in=Subquery(ControlPoint.objects.filter(location_id=<your_location_id>).values('id')))
所以我使用了 route_id
因为当你的模型中有一个 ForeignKey
时,说 x
它被存储为 x_id
我认为这更具可读性但如果你愿意,你当然可以使用路线。
比如我有模型:
class Location(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
...
class ControlPoint(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
location = models.ForeignKey(Location, related_name='+', on_delete=models.CASCADE, verbose_name='Локация')
order = models.IntegerField(default=0)
route = models.ForeignKey('Route', related_name='control_points', on_delete=models.CASCADE)
...
class Route(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
@property
def get_departure(self):
return self.control_points.get(order=0)
@property
def get_arrival(self):
return self.control_points.order_by('-order')[0]
def clear_control_points(self):
self.control_points.all().delete()
class Trip(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
route = models.OneToOneField(Route, related_name='trips', null=True, on_delete=models.SET_NULL)
user = models.ForeignKey(User, related_name='trips', on_delete=models.CASCADE)
...
解决
根据以下cengineer的回答(非常感谢他):
Trip.objects.filter(route_id__in=Subquery(ControlPoint.objects.filter(location_id=<location_id>).values('route_id')))
如果你知道如何以不同的方式解决这个问题,我会很高兴看到你的例子。
是的,您可以使用子查询解决此问题。在你的情况下应该是这样的
Trip.objects.filter(route_id__in=Subquery(ControlPoint.objects.filter(location_id=<your_location_id>).values('id')))
所以我使用了 route_id
因为当你的模型中有一个 ForeignKey
时,说 x
它被存储为 x_id
我认为这更具可读性但如果你愿意,你当然可以使用路线。