django:带有查询集值的选择显示

django: choice display with queryset values

我想在模板上使用 get_status_display,来自仅包含模型中一些字段的查询集。

我有一个带有选择字段(状态)的模型。

class Operation(models.Model, ModelMixin):
    operation_area = models.ForeignKey('operations.OperationArea', null=True)

    created = models.DateTimeField(auto_now=True)
    indication = models.NullBooleanField()
    observation = models.TextField(blank=True, null=True)
    rate = models.IntegerField(blank=True, null=True)
    scheduling = models.DateTimeField(blank=True, null=True)
    status = models.IntegerField(choices=OPERATION_TYPE)

class OperationArea(models.Model, ModelMixin):
    campaign = models.ForeignKey('campaigns.Campaign')
    person = models.ForeignKey('registrations.Person')
    user = models.ForeignKey('authentication.User')

    area = models.CharField(max_length=1, choices=OPERATION_AREA)

我的查询是:

Operation.objects.filter(operation_area__user=user).values('id', 'created', 'operation_area__person__name', 'status')

从这里得到一个字典,但是 get_FOO_dislpay 是一个实例方法,不适用于字典。我不想使用 .only() 因为他带来了 operation_area 对象并得到 person.name 他进行另一个查询,例如 operation.operation_area.person.name。任何想法如何使用一个查询和 get_FOO_display?

我认为 annotate() 是您要找的。

Annotates each object in the QuerySet with the provided list of query expressions. An expression may be a simple value, a reference to a field on the model (or any related models), or an aggregate expression (averages, sums, etc.) that has been computed over the objects that are related to the objects in the QuerySet.

Each argument to annotate() is an annotation that will be added to each object in the QuerySet that is returned.

The aggregation functions that are provided by Django are described in Aggregation Functions below.

Annotations specified using keyword arguments will use the keyword as the alias for the annotation. Anonymous arguments will have an alias generated for them based upon the name of the aggregate function and the model field that is being aggregated. Only aggregate expressions that reference a single field can be anonymous arguments. Everything else must be a keyword argument.

你应该使用:

operations.annotate(person_name=F('operation_area__person__name')) 

看看https://docs.djangoproject.com/en/2.0/ref/models/querysets/#annotate

我知道现在回复已经很晚了。尽管如此,我认为我的解决方案还是值得分享的:

def display_value(choices,field):
    options = [
         When(**{field: k, 'then': Value(v) })
          for k,v in choices
    ]
    return Case(
        *options,output_field=CharField()
    )

你可以使用:

my_field = {'field_value': display_value(CHOICES, 'field'),}
YourModel.objects.annotate(**my_field)