在我的models.py中,我过滤了两种情况。我检查是否有
ticket_on_sale
ticket_on_sale_soon
如果给出2)但没有给出1),则该方法应返回True
。我在变量级别上进行过滤(在数据库已经命中之后)。我想知道是否有更可靠的方法。我做的不对。你有建议吗?
models.py
class Event(TimeStampedModel):
organizer = models.ForeignKey(
Organizer,
on_delete=models.PROTECT,
related_name='events',
) # PROTECT = don't allow to delete the organizer if an event exists
name = models.CharField(
max_length=50,
verbose_name=_("Event Title"),
)
slug = models.SlugField(
validators=[SlugBlackList()],
verbose_name=_("Event Link"),
)
currency = models.CharField(
max_length=10,
choices=CURRENCY_CHOICES,
verbose_name=_("Currency"),
)
status = models.CharField(
max_length=8,
choices=EventStatus.CHOICES,
default=EventStatus.DRAFT,
verbose_name=_("Status"),
)
venue_address = models.TextField(
null=True,
blank=True,
verbose_name=_("Location address"),
)
start_date = models.DateTimeField(verbose_name=_("Start date"))
end_date = models.DateTimeField(verbose_name=_("End date"))
@cached_property
def only_scheduled_tickets(self):
tickets = self.tickets.all()
ticket_on_sale = list(filter(
lambda ticket: ticket.is_on_sale() and ticket.is_available(),
tickets,
))
ticket_on_sale_soon = list(filter(
lambda ticket: ticket.is_on_sale() and not ticket.is_available(),
tickets,
))
if ticket_on_sale_soon and not ticket_on_sale:
return True
class Ticket(TimeStampedModel):
event = models.ForeignKey(
Event,
on_delete=models.CASCADE,
related_name='tickets',
) # CASCADE = delete the ticket if the event is deleted
tax = models.ForeignKey(
'Tax',
on_delete=models.PROTECT,
related_name='tickets',
blank=True,
null=True,
) # PROTECT = don't allow to delete the ticket tax if a ticket exists
name = models.CharField(
max_length=100,
verbose_name=_("Ticket Name"),
)
price_gross = models.PositiveIntegerField(
verbose_name=_("Price gross"),
)
description = models.TextField(
null=True,
blank=True,
)
start_at = models.DateTimeField(
null=True,
blank=True,
verbose_name=_("Ticket sale starts at"),
)
end_at = models.DateTimeField(
null=True,
blank=True,
verbose_name=_("Ticket sale ends at"),
)
quantity = models.PositiveIntegerField(
verbose_name=_("Quantity"),
)
status = models.CharField(
max_length=8,
choices=TicketStatus.CHOICES,
default=TicketStatus.ON_SALE,
verbose_name=_("Status"),
)
答案 0 :(得分:0)
为了在TicketQuerySet上获得on_sale_soon
字段,您可能需要注释,例如
from datetime import date
from django.db import models
from django.db.models import Q, Value
tickets = Ticket.objects.annotate(
on_sale_soon=Case(
When(start_at__lte=date.today() + datetime.timedelta(days=10), then=Value(True, models.BooleanField())),
default=Value(False, models.BooleanField()),
output_field=models.BooleanField()
)
)
)
之后,如果您想很快获得但尚未出售的门票,则可以
tickets = tickets.objects.exclude(status=TicketStatus.ON_SALE)
tickets = tickets.filter(on_sale_soon=True)
这样做的优点是,所有操作都将在一次查询中在数据库服务器上完成。