0

I currently am making a simple newspaper Django application, and am working on the Articles model which looks as follows:

class Article(models.Model):
    title = models.CharField(max_length=255)
    body = models.TextField()
    #date = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(
        get_user_model(),
        on_delete=models.CASCADE, 
    )
    topic = models.CharField(max_length=255)
    score_choices = [(-5,'-5'), (-4, '-4'), (-3,'-3'), (-2, '-2'), (-1,'-1'), 
    (0,'0'),(1,'1'), (2,'2'), (3,'3'), (4,'4'), (5,'5')]
    score = models.IntegerField(choices=score_choices, default=0)


I am attempting to create another model that looks something like this:

class Topic(models.Model):
    topic_name = models.CharField(max_length=255)
    average_score =

Within the topic model, what I would like to do is somehow query all the Articles that have topic_name as their topic, and then return a list of scores that have been entered for Articles with that topic.

I'm currently pretty lost on this issue and I'm not even sure anymore if using the Django models is the best route. I've been reading through the Django Documentation as well as Third-Party books for a while but I can't find any reference here.

To summarize, I have two models: Article and Topic. Article has a field called 'topic' as well and I would like to create a field for my Topic class that is a function of the score field for all Article objects whose 'topic' field agrees with that of my separate Topic class. I apologize if this is confusing and I don't know all the terminology as I am trying to teach myself.

I have read through Django Documentation's pages on Models, Queries, Many-to-Many Relationships and various other properties. I still am unsure as to the solution.

1
  • How are you creating your Topic instances? Commented Sep 19, 2019 at 15:02

1 Answer 1

1

Something like the following would work, using aggregation:

from django.db.models.aggregates import Avg

class Topic(models.Model):
    topic_name = models.CharField(max_length=255)

    def average_score(self):
        return Article.objects.filter(topic=self.topic_name).aggregate(avg=Avg('score')).get('avg')
Sign up to request clarification or add additional context in comments.

6 Comments

Correct, but I would argue that this would probably not require a new model, not sure when or how or even why OP would actually create the Topic instances. You might want to consider making average_score_for_topic(cls, topic_name) class method on the Article class instead.
Agreed, or make topic a foreign key on Article
Thank you for your help! As a quick follow-up, if I make topic a foreign key within Article, will I still be able to collect "statistics" on it, similar to how I collected the Average before. And, if I were to be interested in other properties of the topic: say a "region" it pertains to, etc. would it make more sense to use a Foreign Key or a new model?
Not quite sure what you mean exactly. A foreign key is a relation to another model. Whether you want a topic/region/(any attribute) to be a proper model or choice field or free text field depends: Does the attribute have properties of its own that you want to control, are all possible cases known in advance or should admins be able to add new ones, ...
And yes you will be able :)
|

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.