Django:过滤器变量

时间:2019-05-03 01:34:42

标签: python django

在我的models.py中,我过滤了两种情况。我检查是否有

  1. 一个ticket_on_sale
  2. 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"),
        )

1 个答案:

答案 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)

这样做的优点是,所有操作都将在一次查询中在数据库服务器上完成。