class Customer(models.Model):
name = models.CharField(max_length=189)
class Message(models.Model):
message = models.TextField()
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name="messages")
created_at = models.DateTimeField(auto_now_add=True)
我在这里想要做的是,我想获得由Message.created_at排序的不同客户的查询集。我的数据库是mysql。
我尝试了以下方法。
qs = Customers.objects.all().order_by("-messages__created_at").distinct()
m = Messages.objects.all().values("customer").distinct().order_by("-created_at")
m = Messages.objects.all().order_by("-created_at").values("customer").distinct()
最后,我使用了一组工具来完成此操作,但是我认为我可能会丢失一些东西。我当前的解决方案:
customers = set(Interaction.objects.all().values_list("customer").distinct())
customer_list = list()
for c in customers:
customer_list.append(c[0])
编辑 是否可以获取根据其上一条消息时间排序的客户列表,但queryset还将包含上一条消息值作为另一个字段?
答案 0 :(得分:2)
您要根据您的评论,根据客户的最新消息订购客户。我们可以通过注释 Customer
来实现,然后对注释进行排序:
from dango.db.models import Max
Customer.objects.annotate(
last_message=Max('messages__crated_at')
).order_by("-last_message")
一个潜在的问题是对根本没有写任何消息的Customer
做什么。在这种情况下,Python中的last_message
属性将是NULL
(None
)。我们可以在nulls_first
表达式的nulls_last
中用.order_by
或F
进行指定。例如:
from dango.db.models import F, Max
Customer.objects.annotate(
last_message=Max('messages__crated_at')
).order_by(F('last_message').desc(nulls_last=True))
一个不错的好处是,此查询集的Customer
对象将具有一个额外的属性:.last_message
属性将指定用户最后一次写入时的时间一条消息。
您还可以决定将其过滤掉,例如:
from dango.db.models import F, Max
Customer.objects.filter(
messages__isnull=False,
).annotate(
last_message=Max('messages__crated_at')
).order_by('-last_message')