1

I have two models where users create a post and comment on that post. When users comment this post I want updating last_message date on UserPost model. If there are no comments yet I want the default last_message date to be set to the date the post was created.

Models:

class UserPosts(models.Model):
   postTitle = models.CharField(max_length=100, verbose_name="Title")
   postContent = RichTextField(null=True, verbose_name="Content")
   created_at = models.DateTimeField(
                auto_now_add=True, verbose_name="Date of upload")
   last_message = ?????????????????

   def __str__(self):
       return self.postTitle



class UserMessages(models.Model):
    postMessages = RichTextField(null=True, verbose_name="Message")
    post = models.ForeignKey(
             UserPosts, on_delete=models.CASCADE, verbose_name="Linked Post", null=True)
   created_at = models.DateTimeField(auto_now_add=True, verbose_name="Date of upload")

EDİT

MY VİEWS:

def forums(request,forumname):
   forum = Category.objects.get(categoryName=forumname)
   post2 = UserPosts.objects.all().filter(category=forum.id).order_by("- 
                     usermessages").filter(category=forum.id)
   context = {
      'posts': post2,
   }
   return render(request, "_forums.html",context)

MY TEMPLATE:

    {% for post in posts %}
       <div class="mb-2 text-muted">
           {{post.last_message | naturaltime}}
       </div>
    {% endfor %}

I couldn't find anything relevant to this topic in the Django docs, Google, and other sources.

Turing
  • 124
  • 1
  • 7

1 Answers1

1

If it is an option to not have it at the database, you can just calculate this at the time when you need it. So for that you can use a model property:

class UserPosts(models.Model):
    postTitle = models.CharField(max_length=100, verbose_name="Title")
    postContent = RichTextField(null=True, verbose_name="Content")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="Date of upload")
    
    @property
    def last_message(self):
        last_message = self.usermessages_set.order_by('-created_at').first()
        if last_message:
            return last_message.created_at
        return self.created_at

So if a post doesn't have a message yet, it will get it's own created_at field. You can then use this like a property:

post = UserPosts.objects.first()
print(post.last_message)

Also consider using cached_property if you plan to use this field in a view multiple times.

Brian Destura
  • 11,487
  • 3
  • 18
  • 34
  • thank you sir its working but there is a problem. When trying to display posts in my template file, they are not sorted by last message date and another thing I was wondering is that you used the usermessages_set object in the last_message function. What does this mean? I am editing my views file and html file to help you. thanks – Turing Aug 17 '21 at 21:59
  • 1
    It's the backward relationship that allows you to access the reverse of the foreign key (userposts -> usermessages). You can find the explanation and some examples [here](https://docs.djangoproject.com/en/3.2/topics/db/queries/#following-relationships-backward) – Brian Destura Aug 17 '21 at 23:53
  • 1
    For ordering, it's a little bit tricky because you case depends on a multi-valued field. Try to read [this](https://docs.djangoproject.com/en/3.2/ref/models/querysets/#order-by) first especially the first note. – Brian Destura Aug 18 '21 at 00:01
  • 1
    Otherwise you can do something like [this](https://stackoverflow.com/a/8478586/6759844) – Brian Destura Aug 18 '21 at 01:09