1

I'm interacting with a legacy db on another system, so the models are written in stone and not very django-ey.

My models.py:

class Site(models.Model):
    site_code = models.CharField(max_length=30, primary_key=True)
    name = models.CharField(unique=True, max_length=300)

class Document(models.Model):
    id = models.IntegerField(primary_key=True)
    site_ref = models.ForeignKey(Site)
    description = models.CharField(max_length=1500)

class DocumentStatusCategory(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(unique=True, max_length=90)

class DocumentStatus(models.Model):
    id = models.IntegerField(primary_key=True)
    document = models.ForeignKey(Document)
    status = models.ForeignKey(DocumentStatusCategory)
    changed_by = models.ForeignKey(User)
    created_at = models.DateTimeField()

In my views.py I want to retrieve a queryset with all the Document objects that belong to a specified Site (say site_ref=mysite) which do not have any related DocumentStatus objects with status=4.

Any idea how I can do this as a single (non-sql intensive) line?

2 Answers 2

2
Document.objects.filter(site_ref=mysite).exclude(documentstatus__status_id=4)
Sign up to request clarification or add additional context in comments.

2 Comments

Keep forgetting the relation span across a reverse relation. Can't it just be documentstatus__status_id though?
aha, I didn't know you could call the relation like that. Thank you!
1
Document.objects.filter(site_ref=site_obj).exclude(documentstatus_set__in=DocumentStatus.objects.filter(status_id=4))

Not exactly one query, but I don't think that's achievable without going down to raw sql. Two queries isn't bad though I suppose.

I should mention that the above assumes that the reverse relation between Document and DocumentStatus is documentstatus_set. You can explicitly state what the reverse relation is like so:

# inside the DocumentStatus model definition
document = models.ForeignKey(Document, related_name='document_statuses')

Then the query becomes:

Document.objects.filter(site_ref=site_obj).exclude(document_statuses__in=DocumentStatus.objects.filter(status_id=4))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.