【问题标题】:Use different model's field with the same value in Django在 Django 中使用具有相同值的不同模型的字段
【发布时间】:2015-08-22 17:37:44
【问题描述】:

我有两个 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 完成相同但更简洁的方法?

【问题讨论】:

    标签: python django orm 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()
    

    【讨论】:

      【解决方案2】:

      我认为您可以尝试使用注释而不是额外的来解决这个问题。注释将允许您使用新创建的字段进行过滤。更多信息:https://docs.djangoproject.com/en/1.8/topics/db/aggregation/

      顺便说一句,因为您的汽车上似乎总是需要engine_status。为什么不在 Car 模型上创建一个字段,并在每次创建 CarModification 时使用信号设置其状态?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-05
        • 1970-01-01
        • 2018-06-16
        • 1970-01-01
        • 2020-01-30
        • 2021-11-14
        • 2019-02-13
        相关资源
        最近更新 更多