Kingsley
Kingsley

Reputation: 825

Check the results of one queryset against the results of another queryset django

In my django application I have three models, People, Reviews and File.

class People(models.Model):
  firstname = models.charField(max_length=20)
  lastname = models.charField(max_length=20)

class Reviews(models.Model):
  STATUSES = (
    ('pending', 'Pending'),
    ('approved', 'Approved'),
    ('rejected', 'Rejected')
  )
  person = models.OneToOneField(People, on_delete=models.CASCADE, primary_key=True)
  status = models.CharField(max_length=10, choices=STATUSES, default='pending')
  comment = models.TextField()

class File(models.Model):
  owner = models.OneToOneField(Reviews, on_delete=models.CASCADE, primary_key=True)
  comment = models.TextField()
  issue_date = models.DateField(auto_now_add=True)

See that OneToOneField on the File model? I need to be able to filter that dropdown, based on two conditions.

  1. It needs to only display records from the Reviews model that have a status of approved. Reviews.objects.filter(status="approved")
  2. The displayed results must not already exist in the File model's records. File.objects.all()

And also, while creating an instance of the File model, when a value is selected from the dropdown, how could I automatically populate the comment field with the value from the Review model's comment field?

I can't quite figure it out.

Upvotes: 0

Views: 76

Answers (1)

ruddra
ruddra

Reputation: 52028

I think you can try like this:

Reviews.objects.filter(status="approved", file__isnull=True)

Here due to OneToOne relationship, all reviews object has a file attribute which returns a File Object. I am using isnull to check if it is empty or not.

Update

IMHO, I don't see why the value of the comment should be stored twice in the Database. If you have the comment value in Review, then you can access it like this:

file = File.objects.first()
comment = file.review.comment

Now, when it comes to showing it in admin site while creating File Instance, its not possible to do that without using Javascript. But another hackish approach is to display that value in the review dropdown. But for that, you need to override the __str__ method of Review Model. Like this:

class Reviews(models.Model):
  STATUSES = (
    ('pending', 'Pending'),
    ('approved', 'Approved'),
    ('rejected', 'Rejected')
  )
  person = models.OneToOneField(People, on_delete=models.CASCADE, primary_key=True)
  status = models.CharField(max_length=10, choices=STATUSES, default='pending')
  comment = models.TextField()

  def __str__(self):
     return "{}: {}".format(self.status, self.comment)

But, if a file instance is created, or if you want to show comment in the file list in admin site, you can do that like this:

from django.contrib import admin

class FileAdmin(admin.ModelAdmin):
    list_display = ('issue_date', 'comment')

    def comment(self, obj):
        return obj.review.comment

admin.site.register(File, FileAdmin)

Upvotes: 2

Related Questions