Hi, I would like to improve my solution here a bit, I do hope someone could provide some tips for me. Admins upload a Reportfile, and via a Sendtask parts of those files are sent to the Recipients. Sometimes Sendtasks fail and can be restarted, so it might be that a Recipient has 3 different Sendtasks referring to the same Reportfile. In the end, I want to have RecipientRecentListView display only those recipients who have received a Reportfile within the last 14 days.
So, basically, I think there are more elegant ways than my solution in the ListViews get_queryset, maybe some of you more experienced django programmers can point me to some magic filter foo - or any other ideas are highly welcome. Thanks in advance!
class Sendtask(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
recipient = models.ForeignKey(Recipient, on_delete=models.CASCADE)
reportfile = models.ForeignKey(Reportfile, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["-created_at"]
class Recipient(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
fullname = models.CharField(max_length=28, default="")
class Reportfile(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
uploaded_at = models.DateTimeField(auto_now_add=True)
class RecipientRecentListView(ListView):
template_name = "recipient_recent.html"
model = Recipient
context_object_name = 'Recipient'
def get_queryset(self):
now = datetime.datetime.now().date()
qs = super().get_queryset()
recent_receipients = []
for i in qs:
if i.sendtask_set.first().reportfile.uploaded_at > (now - datetime.timedelta(days = 14)):
recent_receipients.append(i.id)
final_qs = qs.filter(id__in = recent_receipients)
return final_qs
(I suggest you try this in the Django shell - that’s the easiest way to test queries like this.)
Side Note: Logically, what you have created here is a ManyToMany relationship between Recipient and ReportFile with SendTask as the through model containing additional data. Depending upon your use of this in the rest of your system, you may get value out of making that relationship explicit, allowing the use of the ManyToMany queryset API.
thanks for the fast response. I have already tried various things via django-extensions shell_plus, but haven’t managed to find a working, more elegant solution. The code you suggested unfortunately delivers
In the list that it shows the choices, does it have sendtask? If so, use that instead. (I do frequently get the two situations confused about when I need to use _set and when not.)
I also had the impression I could use _set with the queryset, but unfortunately I can only use sendtask_set with single instances of the queryset, not on the queryset itself. Thats why I chose to use the for loop and iterate over the items of the queryset, and for each item fetching the most recent sendtask and comparing it and then adding the primary key (uuid in this case) into a list.
aaah, great, I was probably sitting too long on that problem. I completely overread that sendtask (instead of sendtask_set) was in that list, sorry. Problem solved! Thank you very much! For the curious: on my local machine your solution is 182 times faster than my loops in the initial post