根据第一个 child 模型的属性排序查询集,returns 重复 objects。姜戈,DRF
Ordering queryset based on its first child model's attributes, returns duplicated objects. Django, DRF
我的查询集有问题。
我正在使用 Django Rest Framework return:
- 所有事件的列表,
- 有状态="Published"
- 排序依据:最近即将举行的活动排在第一位。
问题:
有些活动有多个日期。这就是为什么我将日期分隔在不同的模型中。
现在我想根据第一个日期 (Child) 对事件 (Parent) 进行排序。
这是我正在尝试做的事情:
class EventViewSet(viewsets.ModelViewSet):
"""
API Endpoint to retrieve Events
"""
today = timezone.now().date()
published_events = Event.objects.filter(status__exact="Published")
ordered_events = published_events.order_by('date__start_date')
queryset = ordered_events
serializer_class = EventSerializer
lookup_field = 'slug'
这是我的模型:
事件(Parent):
class Event(TimeStampedModel):
DRAFT = "Draft"
EXPIRED = "Expired"
PRIVATE = "Private"
PUBLISHED = "Published"
EVENT_STATUS_CHOICES = [
(DRAFT, 'Draft'),
(EXPIRED, 'Expired'),
(PRIVATE, 'Private'),
(PUBLISHED, 'Published')
]
name = models.CharField(max_length=250)
location = models.ForeignKey(Location, on_delete=models.CASCADE)
description = models.TextField(blank=True)
status = models.CharField(max_length=50, choices=EVENT_STATUS_CHOICES, default=DRAFT)
def event_dates(self):
"""
Returns all dates of an event
"""
try:
date_list = []
for date in self.dates.order_by('start_date'):
date_list.append(date.start_date.date())
return date_list
except IndexError:
return "No Dates Specified"
def event_start_date(self):
"""
Returns the start date of the event
"""
try:
return self.dates.order_by('start_date')[0].start_date.date()
except IndexError:
return "No Date Specified"
def event_start_time(self):
"""
Returns the start time of the event
"""
try:
return self.dates.order_by('start_date')[0].start_date.time()
except IndexError:
return "No Time Specified"
日期模型(Child):
class EventDate(TimeStampedModel):
event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name="dates")
start_date = models.DateTimeField()
end_date = models.DateTimeField(null=True)
history = HistoricalRecords()
def __str__(self):
return str(self.start_date)
我搜索了是否可以使用模型方法,但是order-by发生在服务器端,无法调用它。
我如何 return 一个基于第一个 child 日期 start_date 排序的查询集,而不 return 为每个 child?
如果这听起来令人困惑,请告诉我,我会尽力澄清。
谢谢!
您可以先注释最大 child 的日期,然后按此值排序查询:
from django.db.models import Max
ordered_events = published_events.annotate(max_chuld_date=Max("date__start_date")).order_by("max_chuld_date")
您可以在事件模型中添加一个名为 first_date 的字段并将其填充到保存信号中。
它是重复的,但至少它简化了您的查询。
class Event(TimeStampedModel):
...
first_start_date = models.DateTimeField()
在信号中:
def event_post_save(*, signal, instance, created, raw, **kwargs):
start_dates = [i.start_date for i in instance.dates.values('start_date')]
start_dates.sort()
try:
instance.first_start_date = start_dates[0]
except IndexError:
pass
代码未经测试,但它给了你想法。
我的查询集有问题。 我正在使用 Django Rest Framework return:
- 所有事件的列表,
- 有状态="Published"
- 排序依据:最近即将举行的活动排在第一位。
问题:
有些活动有多个日期。这就是为什么我将日期分隔在不同的模型中。
现在我想根据第一个日期 (Child) 对事件 (Parent) 进行排序。
这是我正在尝试做的事情:
class EventViewSet(viewsets.ModelViewSet):
"""
API Endpoint to retrieve Events
"""
today = timezone.now().date()
published_events = Event.objects.filter(status__exact="Published")
ordered_events = published_events.order_by('date__start_date')
queryset = ordered_events
serializer_class = EventSerializer
lookup_field = 'slug'
这是我的模型:
事件(Parent):
class Event(TimeStampedModel):
DRAFT = "Draft"
EXPIRED = "Expired"
PRIVATE = "Private"
PUBLISHED = "Published"
EVENT_STATUS_CHOICES = [
(DRAFT, 'Draft'),
(EXPIRED, 'Expired'),
(PRIVATE, 'Private'),
(PUBLISHED, 'Published')
]
name = models.CharField(max_length=250)
location = models.ForeignKey(Location, on_delete=models.CASCADE)
description = models.TextField(blank=True)
status = models.CharField(max_length=50, choices=EVENT_STATUS_CHOICES, default=DRAFT)
def event_dates(self):
"""
Returns all dates of an event
"""
try:
date_list = []
for date in self.dates.order_by('start_date'):
date_list.append(date.start_date.date())
return date_list
except IndexError:
return "No Dates Specified"
def event_start_date(self):
"""
Returns the start date of the event
"""
try:
return self.dates.order_by('start_date')[0].start_date.date()
except IndexError:
return "No Date Specified"
def event_start_time(self):
"""
Returns the start time of the event
"""
try:
return self.dates.order_by('start_date')[0].start_date.time()
except IndexError:
return "No Time Specified"
日期模型(Child):
class EventDate(TimeStampedModel):
event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name="dates")
start_date = models.DateTimeField()
end_date = models.DateTimeField(null=True)
history = HistoricalRecords()
def __str__(self):
return str(self.start_date)
我搜索了是否可以使用模型方法,但是order-by发生在服务器端,无法调用它。
我如何 return 一个基于第一个 child 日期 start_date 排序的查询集,而不 return 为每个 child?
如果这听起来令人困惑,请告诉我,我会尽力澄清。
谢谢!
您可以先注释最大 child 的日期,然后按此值排序查询:
from django.db.models import Max
ordered_events = published_events.annotate(max_chuld_date=Max("date__start_date")).order_by("max_chuld_date")
您可以在事件模型中添加一个名为 first_date 的字段并将其填充到保存信号中。
它是重复的,但至少它简化了您的查询。
class Event(TimeStampedModel):
...
first_start_date = models.DateTimeField()
在信号中:
def event_post_save(*, signal, instance, created, raw, **kwargs):
start_dates = [i.start_date for i in instance.dates.values('start_date')]
start_dates.sort()
try:
instance.first_start_date = start_dates[0]
except IndexError:
pass
代码未经测试,但它给了你想法。