Search code examples
djangodjango-templatesdjango-template-filters

Django template tags conditionals


Right, am struggling with my blog app when trying to render some logic through the template view. So the idea is to render a one time only button for the newly authenticated users that do not have a post published and after the user has published its first post the button will be rendered within a for loop so he/she'll be able to create/delete a new one from there.

views.py

@login_required(login_url='app_users:login')
@allowed_users(allowed_roles=['admin', 'staff', 'users'])
def blog(request):
    posts = BlogPost.objects.all().order_by('date_posted')
    context = {'title': 'Blog', 'posts': posts}
    return render(request, 'app_blog/blog.html', context)

models.py

class BlogPost(models.Model):
    title = models.CharField(max_length=100, null=True)
    content = models.TextField(null=True)
    date_posted = models.DateTimeField(default=timezone.now, null=True, blank=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

blog.html

    {% block content %}
    
        {% if request.user not in posts|last %}
            <div class="container" style="float: left;">
                <a class="btn btn-primary btn-sm mt-1 mb-1" href="{% url 'app_blog:blog_create' user.id %}"><h5>C'mon {{ request.user.username }}, don't be shy! Create Your First Blog Post!</h5></a>
            </div>
        {% endif %}
        <br>
        <br>
        {% for post in posts %}
        <br>
            <div class="container">
                <article class="media content-section">
                    <img class="rounded-circle account-img" src="{{ post.author.profile.image.url }}" alt="Image could not be uploaded!">
                    <div class="card-body media-body">
                        <div class="article-metadata">
                            <a class="mr-2" href="{% url 'app_blog:blog_user_detail' post.id %}">{{ post.author }}</a>
                            <small class="text-muted">{{ post.date_posted|date:"d F Y" }}</small>
                        </div>
                        <div class="article-metadata">
                            {% if post.author == request.user %}
                                <div>
                                    <a class="btn btn-primary btn-sm mt-1 mb-1" href="{% url 'app_blog:blog_create' post.id %}">Create New Post</a>
                                    <a class="btn btn-primary btn-danger btn-sm mt-1 mb-1" href="{% url 'app_blog:blog_delete' post.id %}">Delete</a>
                                </div>
                            {% endif %}
                        </div>
                        <h2><a class="article-title" href="{% url 'app_blog:blog_detail' post.id %}">{{ post.title }}</a></h2>
                        <p class="article-content">{{ post.content|safe }}</p>
                    </div>
                </article>
            </div>
        <br>
        {% endfor %}
    
    {% endblock %}

So, again, end question would be about what sort of conditionals to use here:

{% if request.user not in posts|last %}

Thanks.


Solution

  • Not quite sure I fully understand but I will suggest something. A user who was a saved post should not see that button? If so, maybe something like this would work:

    {% if request.user not in posts.authors.all %}
    

    EDIT original solution won't work. posts is a queryset object

    views.py

    @login_required(login_url='app_users:login')
    @allowed_users(allowed_roles=['admin', 'staff', 'users'])
    def blog(request):
        posts = BlogPost.objects.all().order_by('date_posted')
        new_user = len(posts.filter(author=request.user)) == 0
        context = {'title': 'Blog', 'posts': posts, 'new_user': new_user}
        return render(request, 'app_blog/blog.html', context)
    

    blog.html (just the condition)

    {% if new_user %}