在 Django 中使用具有相同值的不同模型字段
Use different model's field with the same value in Django
我有两个 Django 模型,我想在两个模型中都有相同的值字段。基本上,当 CarModification.engine_status
是 'inactive'
或 'active'
时,我想将 Car 中的相同字段设置为最新的 CarModification
的字段值。
class CarManager(models.Manager):
def get_queryset(self):
# Select engine_status from the latest
# carmodification. If there are no modifications,
# use default 'inactive'
return super(CarManager, self).get_queryset().extra(
select={
'engine_status': "SELECT COALESCE ( "
" (SELECT engine_status "
" FROM carmodifications "
" WHERE cars.id = carmodifications.car_id "
" ORDER BY carmodifications.created_at DESC "
" LIMIT 1), 'inactive')"
)
class Car(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = CarManager()
class CarModification(models.Model):
CHOICES = (
('active', 'Active')
('inactive', 'Inactive')
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
comment = models.CharField()
engine_status = models.CharField(default='inactive', choices=CHOICES)
car = models.ForeignKey(Car, related_name='modifications')
这很好用,但我还希望能够通过这个额外的字段过滤 Car 对象。这对于更多 SQL 查询是可能的,但它变得(而且我认为它已经)非常难看。有没有一种方法可以使用 Django ORM 完成相同但更简洁的方法?
我认为您可以尝试使用注释而不是额外的方式来解决这个问题。注释将允许您使用新创建的字段进行过滤。更多信息:https://docs.djangoproject.com/en/1.8/topics/db/aggregation/.
顺便说一句,因为您的汽车似乎总是需要 engine_status
。为什么不在 Car 模型上创建一个字段,并在每次创建 CarModification 时使用信号设置其状态?
我更喜欢在这种情况下使用 signal
:
class Car(models.Model):
engine_status = models.CharField(max_length=256, default='inactive')
class CarModification(models.Model):
CHOICES = (
('active', 'Active'),
('inactive', 'Inactive')
)
engine_status = models.CharField(max_length=256, default='inactive', choices=CHOICES)
car = models.ForeignKey(Car, related_name='modifications')
@receiver(post_save, sender=CarModification)
def pre_save_handler(sender, **kwargs):
"""after saving CarModification, change car's engine_status"""
instance = kwargs.get('instance')
if instance.car_id:
current_car = Car.objects.filter(id=instance.car_id)[0]
current_car.engine_status = instance.engine_status
current_car.save()
我有两个 Django 模型,我想在两个模型中都有相同的值字段。基本上,当 CarModification.engine_status
是 'inactive'
或 'active'
时,我想将 Car 中的相同字段设置为最新的 CarModification
的字段值。
class CarManager(models.Manager):
def get_queryset(self):
# Select engine_status from the latest
# carmodification. If there are no modifications,
# use default 'inactive'
return super(CarManager, self).get_queryset().extra(
select={
'engine_status': "SELECT COALESCE ( "
" (SELECT engine_status "
" FROM carmodifications "
" WHERE cars.id = carmodifications.car_id "
" ORDER BY carmodifications.created_at DESC "
" LIMIT 1), 'inactive')"
)
class Car(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = CarManager()
class CarModification(models.Model):
CHOICES = (
('active', 'Active')
('inactive', 'Inactive')
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
comment = models.CharField()
engine_status = models.CharField(default='inactive', choices=CHOICES)
car = models.ForeignKey(Car, related_name='modifications')
这很好用,但我还希望能够通过这个额外的字段过滤 Car 对象。这对于更多 SQL 查询是可能的,但它变得(而且我认为它已经)非常难看。有没有一种方法可以使用 Django ORM 完成相同但更简洁的方法?
我认为您可以尝试使用注释而不是额外的方式来解决这个问题。注释将允许您使用新创建的字段进行过滤。更多信息:https://docs.djangoproject.com/en/1.8/topics/db/aggregation/.
顺便说一句,因为您的汽车似乎总是需要 engine_status
。为什么不在 Car 模型上创建一个字段,并在每次创建 CarModification 时使用信号设置其状态?
我更喜欢在这种情况下使用 signal
:
class Car(models.Model):
engine_status = models.CharField(max_length=256, default='inactive')
class CarModification(models.Model):
CHOICES = (
('active', 'Active'),
('inactive', 'Inactive')
)
engine_status = models.CharField(max_length=256, default='inactive', choices=CHOICES)
car = models.ForeignKey(Car, related_name='modifications')
@receiver(post_save, sender=CarModification)
def pre_save_handler(sender, **kwargs):
"""after saving CarModification, change car's engine_status"""
instance = kwargs.get('instance')
if instance.car_id:
current_car = Car.objects.filter(id=instance.car_id)[0]
current_car.engine_status = instance.engine_status
current_car.save()