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:
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.