2015-06-08 57 views
1

我有兩個Django模型,並且我希望在它們中都有相同的值字段。基本上,當CarModification.engine_status'inactive''active',我想在Car中將相同的字段設置爲最新的CarModification的字段值。在Django中使用不同模型的字段具有相同的值

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') 

這工作正常,但我也希望能夠通過這個額外的字段過濾汽車對象。對於更多的SQL查詢來說,這是可能的,但它會得到(而且我認爲它已經)非常難看。有沒有辦法使用Django ORM來實現相同的,但更乾淨的方式?

回答

1

我更喜歡使用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() 
1

我認爲你可以試着用註解來解決這個問題,而不是用額外的解決方案。註釋將允許您使用新創建的字段進行過濾。更多信息:https://docs.djangoproject.com/en/1.8/topics/db/aggregation/

順便說一句,因爲它似乎總是需要在您的汽車engine_status。爲什麼不在汽車模型上創建一個字段,並在每次進行CarModification創建時都用信號設置其狀態?

相關問題