How can get Post data form Category in Django?

Viewed 781

I tried using Django a bit. Now I'm stuck with posting issues in the category. I want to know how we can use it. Are there any filters that I should use?

Code in my model.py

   class Category(models.Model):
    title = models.CharField(max_length=255, verbose_name="ชื่อหมวดหมู่")
    content = models.TextField(default='ใส่เนื้อหาบทความ')
    slug = models.SlugField(max_length=200, default='ใส่ลิงค์บทความ ตัวอย่าง /your-post-content')
    parent = models.ForeignKey('self',blank=True, null=True ,related_name='children',on_delete=models.CASCADE)

    class Meta:
        unique_together = ('slug', 'parent',)    
        verbose_name_plural = "categories"  

    def __str__(self):                           
        full_path = [self.title]                  
        k = self.parent
        while k is not None:
            full_path.append(k.title)
            k = k.parent
        return ' -> '.join(full_path[::-1])


class Post(models.Model):
    id = models.AutoField
    category = models.ForeignKey('Category',on_delete=models.CASCADE)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    content_images = models.ImageField(default='media/noimg-l.jpg')
    title = models.CharField(max_length=200,unique=True,default='ใส่ชื่อบทความ')
    content = models.TextField(default='ใส่เนื้อหาบทความ')
    created_date = models.DateTimeField(default=timezone.now)
    published_date = models.DateTimeField(blank=True, null=True)
    post_viewcount = models.PositiveIntegerField(default=0,)
    slug = models.SlugField(max_length=200, default='ใส่ลิงค์บทความ ตัวอย่าง /your-post-content')
    status = models.IntegerField(choices=STATUS , default=1)


    def publish(self):
        self.published_date = timezone.now()
        self.save()

    def __str__(self):
        return self.title

    def get_cat_list(self):
        k = self.category # for now ignore this instance method

        breadcrumb = ["dummy"]
        while k is not None:
            breadcrumb.append(k.slug)
            k = k.parent
        for i in range(len(breadcrumb)-1):
            breadcrumb[i] = '/'.join(breadcrumb[-1:i-1:-1])
        return breadcrumb[-1:0:-1]

and my view.py

   def cat_list(request):
    categories = Category.objects.all()
    return render(request, 'blog/categories.html', {'categories': categories})

def category_detail(request, slug):
    category = get_object_or_404(Category, slug=slug)
    return render(request, 'blog/category_detail.html', {'category': category})

and my urls.py

    urlpatterns = [
    path('', views.post_list, name='post_list'),
    path('createcontent/', views.create_post, name='create_post'),
    path('article/<slug:slug>/', views.post_detail, name='post_detail'),
    path('category/', views.cat_list, name='category'),
    path('category/<slug:slug>/', views.category_detail, name='category_detail'),

]

and last on in my template

    <h1> {{ categories.title }} </h1>
<div class="container">
    <div class="row">

        {% for post in categories %}
        <div class="column">
            <div class="card" style="width: 20rem;">
                <img class="card-img-top" src="{{ post.content_images.url }}" alt="{{ post.title }}">
                <div class="card-body">
                    <b><p class="card-text"> <a href="{% url 'post_detail' post.slug %}"> {{ post.categories.title }} </a></p></b>
                    <p> เขียนโดย {{ post.author }}</p>
                    <p class="card-text"> {{ post.content|safe|slice:":200" }}</p>
                    <div align="center"><button type="button" class="btn btn-outline-secondary"> <a href="{% url 'post_detail' post.slug %}">  อ่านเรื่องนี้ต่อ </a></button> </div>
                </div>
            </div>
        </div>
        {% endfor %}

    </div>
</div>

I try to find information on how to do it on the website Djangogirl and others because I want to have my own small blog project. Don't want to use Wordpress

1 Answers

In your detail view, you pass a single Category object with the name category, not categories. You can iterate over the posts with {% for post in category.post_set.all %}:

<h1> {{ category.title }} </h1>
<div class="container">
    <div class="row">
        {% for post in category.post_set.all %}
        <div class="column">
            <div class="card" style="width: 20rem;">
                <img class="card-img-top" src="{{ post.content_images.url }}" alt="{{ post.title }}">
                <div class="card-body">
                    <b><p class="card-text"> <a href="{% url 'post_detail' post.slug %}"> {{ post.categories.title }} </a></p></b>
                    <p>{{ post.author }}</p>
                    <p class="card-text"> {{ post.content|safe|slice:":200" }}</p>
                    <div align="center"><button type="button" class="btn btn-outline-secondary"> <a href="{% url 'post_detail' post.slug %}"></a></button> </div>
                </div>
            </div>
        </div>
        {% endfor %}
    </div>
</div>

A ForeignKey [Django-doc], django makes a manager in the "target model" to query in the opposite direction. If you do not specify the related_name=… parameter [Django-doc], the related name is the name of the "target model" in lowercase, and a _set suffix (here post_set), so that is the way how you can query the related Posts for a given Category.

Related