0

I have a model called 'Format', and another called 'Department' in my Django project. I also have this model:

class DepartmentFormat(models.Model):
    department = models.ForeignKey(Department, on_delete=models.CASCADE)
    format = models.ForeignKey(Format, on_delete=models.CASCADE)
    status = models.ForeignKey(FormatStatus, on_delete=models.CASCADE, null=True, default=None)

This object may or may not exist for every specific Format object. Not always will there be a DepartmentFormat object which has assigned every existing Format. The FormatStatus class looks like this:

class FormatStatus(models.Model):
    STATUS_CHOICES = (
        (0, 'Received'),
        (1, 'Accepted'),
        (2, 'Rejected')
    )
    status = models.IntegerField(choices=STATUS_CHOICES, default=0)
    description = models.TextField(max_length=80, blank=True, null=True)
    date = models.DateTimeField(auto_now=True)

I want to order all of the Format objects like this:

  • First, all Format objects for which there isn't a DepartmentFormat object that has them, or all those who do have one, and the status in FormatStatus is 0. The order here doesn't matter.
  • Finally, those Format objects for which there is a DepartmentFormat object whose status is either 1 or 2.

I don't know how to do this. I know the department I'm searching, but not which DepartmentFormat objects exist for each Format object.

I tried this in my view:

    def get_queryset(self, **kwargs):
        qs = super(ReviewedTableView, self).get_queryset()
        department = self.request.user.department
        dpt_fmt = DepartmentFormat.objects.filter(department=department)
        format_ids = []
        for obj in dpt_fmt:
            format_ids.append(obj.format.id)
        reviewed = Format.objects.filter(id__in=format_ids).order_by('-petition_date')
        not_reviewed = Format.objects.filter(system=department.system).exclude(id__in=format_ids).order_by('petition_date')
        order_ids = []
        for obj in not_reviewed:
            order_ids.append(obj.id)
            print('Not reviewed: {}'.format(str(obj.id)))
        for obj in reviewed:
            order_ids.append(obj.id)
            print('Reviewed: {}'.format(str(obj.id)))
        return Format.objects.filter(id__in=order_ids)

I want all the not yet reviewed to appear first, and all the reviewed to appear later. However, the order is always based on the ID, and ascending, regardless or all else.

The order_ids is ordered correctly, it does have the IDs of the Format objects in the correct order, but when doing return Format.objects.filter(id__in=order_ids) it automatically sorts them by id. It may be something simple, but I'm a bit lost, and any help would be very useful.

  • The sorting logic is fairly complex, how many rows do you expect in the result, is it possible to sort the results in Python? – Mihai Aug 18 '20 at 19:57
  • @Mihai Sorting in Python is probably not a good idea since this function is supposed to return a queryset, not a list... – AKX Aug 18 '20 at 19:58
  • I was thinking about getting the queryset and filtering in the view/http handler. Of course, if there are a lot of documents it will not work. – Mihai Aug 18 '20 at 19:59
  • What about when there are multiple related rows? – Iain Shelvington Aug 18 '20 at 20:00
  • @IainShelvington When there is a DepartmentFormat, when creating I use a get_or_create(department=department, format=format), so that wouldn't happen, but I do that elsewhere. – Iván Flores Vázquez Aug 18 '20 at 20:04

0 Answers0