简体   繁体   中英

Django - Order and filter on Foreign Key

What is the proper way to order and filter on a ForeignKey key on model like this one?

class Ticket(models.Model):
    name = models.CharField(max_length=250)
    created_time = models.DateTimeField(auto_now_add=True)

    def current(self):
        return TicketUpdate.objects.filter(ticket=self.id).first()

class TicketUpdate(models.Model):
    ticket = models.ForeignKey(Ticket)
    description = models.TextField()
    status = models.CharField(max_length=1, choices=STATUSES, default='N')
    type = models.CharField(max_length=1, choices=TYPES, default='N')
    priority = models.CharField(max_length=1, choices=PRIORITIES, default='D')
    created_time = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_time']

Every ticket has one (at least) or more TicketUpdate related.

I want to:

  • list all the ticket from Ticket and show their current status (the newest TicketUpdate item)
  • order the list by TicketUpdate__created_time or Ticket__created_time
  • filter the list by TicketUpdate__priority or TicketUpdate__type or TicketUpdate__status

I am not sure if I have to make a Queryset on Ticket or on TicketUpdate.

I am not even sure if I need that current() function on the Ticket model: I use it on my ListView to retrieve the TicketUpdate info.

With

Ticket.objects.all().order_by('ticketupdate__created_time')

I get a list ordered but with too many entries.

Everything must run on a sqlite3 db too.

Edit: This filter queryset

Ticket.objects.filter(ticketupdate__status='New').values('name', 'ticketupdate__status').order_by('ticketupdate__created_time')

return all the existing ticket, since all of them have an initial New status. I keep the whole history of a ticket: New , Working , Fixed , NotFixed , Working ("Working" again: that fix did not work and the user reopen the ticket)

So I want to filter just by the latest status: I need all the Working but what if a ticket have both Working and Fixed? I just need to filter on the latest.

Yeah you don't really need that current method.

You could just get the queryset and take the first item;

Ticket.objects.all().order_by('ticketupdate__created_time')[0]

Or take a more django based approach of;

Ticket.objects.all().latest('ticketupdate__created_time')

And if you want to filter things;

Ticket.objects.filter(ticketupdate__status='status').order_by(
    'ticketupdate__created_time')

Ticket.objects.filter(ticketupdate__priority='high').latest(
    'ticketupdate__created_time')

You can try:

For list all the ticket from Ticket and show their current status (the newest TicketUpdate item):

For List:

Ticket.objects.values('name', 'ticketupdate__status')

For latest Ticket Update Object:

TicketUpdate.objects.latest('ticket__created_time')

For ordering the list by TicketUpdate__created_time or Ticket__created_time:

Ticket.objects.values('name', 'ticketupdate__status').order_by('ticketupdate__created_time')

or

Ticket.objects.values('name', 'ticketupdate__status').order_by('created_time')

For filtering the list by TicketUpdate__priority or TicketUpdate__type or TicketUpdate__status:

Ticket.objects.filter(ticketupdate__status='your status choice').values('name', 'ticketupdate__status').order_by('ticketupdate__created_time') # simillary priority

EDIT

As I can see, status field in the TicketUpdate is a Character Field, so that A TicketUpdate object can't have both Working or New Status. If you want to get the object which was lastly updated/created, consider adding auto_now to field created_time and whenever you query using:

Ticket.objects.filter(ticketupdate__status='New').values('name', 'ticketupdate__status').order_by('ticketupdate__created_time')

You will get the list sorted in such order that the last updated/created object will be the first index of that list. Also:

Ticket.objects.filter(ticketupdate__status='New').values('name', 'ticketupdate__status').order_by('ticketupdate__created_time').first()

Will return the latest Ticket data.

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