0

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.

Kingsley
  • 777
  • 1
  • 12
  • 35

1 Answers1

2

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)
ruddra
  • 50,746
  • 7
  • 78
  • 101
  • Great. That seems to solve the first problem. What do you suggest I do about the latter part of the question, regarding automatically populating the `comment` field on the file model based on the selected owner? The value of the comment field should come from the `Reviews` model comments. The two should be the same. – Kingsley Feb 21 '19 at 04:58
  • @NelsonKing how are planning to create instance? if its in HTML, then you need to use javascript to do that. – ruddra Feb 21 '19 at 05:05
  • Is there a way to do this while inside django admin? – Kingsley Feb 21 '19 at 05:06
  • 1
    @NelsonKing I have updated my answer. Hope it helps. – ruddra Feb 21 '19 at 05:14
  • 1
    Maybe this will help: https://stackoverflow.com/questions/21337142/django-admin-inlines-get-object-from-formfield-for-foreignkey – ruddra Feb 21 '19 at 06:09