简体   繁体   中英

Django Generic Foreign Key Sorting

So I have a model that has a generic foreign key relationship with with three other models

class Status(BaseRequestStatus):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

class Request(models.Model):
    name = models.CharField(max_length=50, db_index=True)
    ...some fields
    statuses = GenericRelation(Status, related_query_name='request')

class AnotherRequest(models.Model):
    name = models.CharField(max_length=50, db_index=True)
    ...some fields
    statuses = GenericRelation(Status, related_query_name='another_request')

class ThirdRequest(models.Model):
    name = models.CharField(max_length=50, db_index=True)
    ...some fields
    statuses = GenericRelation(Status, related_query_name='third_request')

So currently I am displaying the statuses with the name in a table. I want to be able to sort by the name. Currently I am sorting it like this.

Status.objects.all().order_by('request__name', 'another_request__name', 'third_request__name')

however with this method all of the 'request' is sorted in a chunk, then 'another_request', then 'third_request'

is there anyway to sort all of these together? I was able to do it by converting it to a list.. but in this case I need to use a Queryset.

Thanks in advance for any help.

If you want them treated the same way (deducing this from the fact that you want them sorted by their common name field) then this indicates that these models have the same base.

Use model inheritance in that case with a base model that is abstract and defines the name field and the generic fkey relation.

class RequestBase(models.Model):
    name = models.CharField(max_length=50, db_index=True)
    statuses = GenericRelation(Status, related_query_name='request')

    class Meta:
        abstract = True

class Request(RequestBase):
    # ... more fields

Status.objects.all().order_by('request__name')

A more general explanation: to be able to sort objects by one attribute, you have to make clear that they all share that same attribute. Either by fetching the values in your own routines and creating lists that are sortable (this would be the qs approach you mentioned) or by creating a common interface - which is this Model inheritance approach.

As long as you are not using table inheritance, though, you will not be able to use the database for sorting (meaning: you cannot use the Django ORM for sorting).

There are certainly other approaches, including those that are outside of Django models: for example generating an additional lookup structure like a search index which will contain your transformed data as required (eg a haystack index).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM