1

Currently I have the properties NumWishes and NumPosts inside my Textbook model. However, these properties are only returning the count for the current textbook. I would like the property to return the count for all textbooks with the current textbook isbn. This doesn't work currently because I have unique_together = ('isbn', 'class_name')in the model.

For example, if I have 3 textbooks with the same isbn but 3 different classes the property will return 1 for each of them. However, I want the property to return 3 for each textbook.

Textbook Model

class Textbook(models.Model):
    textbook_name = models.CharField(max_length=200)
    class_name = models.CharField(max_length=200)
    author = models.CharField(max_length=200)
    isbn = models.CharField(max_length=200)
    semester = models.CharField(max_length=200, default="FALL2015")

# Properties for determing supply and demand
    @property
    def NumWishes(self):
        return self.wishlist_set.count()

    @property
    def NumPosts(self):
        return self.posting_set.count()

    @property
    def DemSup(self):
        if (self.posting_set.count() != 0):
            showmethemoney = float((self.wishlist_set.count()))/(self.posting_set.count())
        else:
            showmethemoney = 0
            return showmethemoney

# Instead of a pk field isbn and class_name together have to be unique
    class Meta:
        unique_together = ('isbn', 'class_name')

    def __str__(self):
        return self.textbook_name

My posting model is below. The wishlist model is very similar to the posting one.

Posting Model

class Posting(models.Model):
    textbook = models.ForeignKey(Textbook)
    condition = models.CharField(max_length=200)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    user = models.ForeignKey(User)
    image = models.ImageField(upload_to='postingpics/%Y/%m/%d', default="/textchange/nophoto.png")
    post_date = models.DateTimeField('date_posted')
    comments = models.CharField(max_length=50, default="")

    def __str__(self):
        return str(self.textbook)

    def was_posted_recently(self):
        return self.post_date >= timezone.now() - datetime.timedelta(days=1)
    was_posted_recently.admin_order_field = 'post_date'
    was_posted_recently.boolean = True
    was_posted_recently.short_description = 'Posted recently'

Thanks :)

Community
  • 1
  • 1
Programmingjoe
  • 2,169
  • 2
  • 26
  • 46

1 Answers1

3

If what I wrote in the comment is true, you can just do:

@property
def NumPosts(self):
    return Posting.objects.filter(textbook__isbn=self.isbn).count()

but this is going to be very inefficient if you are using the property within a loop.

Timmy O'Mahony
  • 53,000
  • 18
  • 155
  • 177
  • I sort of use it in a loop...It will compute that property for all search results when a user searches for a textbook. So usually it will compute it 2 - 10 times but it could be much higher. – Programmingjoe Feb 11 '16 at 19:21
  • If I follow a positive use case though it should be fine. It works great thanks – Programmingjoe Feb 11 '16 at 19:24
  • Otherwise you can use the [extra()](https://docs.djangoproject.com/en/1.9/ref/models/querysets/#extra) queryset method to perform custom queries that are more complicated. [Here's an example](https://timmyomahony.com/blog/filtering-annotations-django/). If the above works out, be sure to accept so the question is considered answered. – Timmy O'Mahony Feb 11 '16 at 19:26