How to show all categories in one django template

Viewed 868

I have been working on a project in which a user can make a post and put it on diferent categories, I have a view that is supposed to display all the posts from all the categories but it is displaying all the categories in order and the posts have to be displayed in a random order mixing all the categories. The error here is that the view is displaying all the categories in order, like first all the posts from the action category and then all the posts from the sports category when it should be mixed. What can I do to display all the posts from all the categories in a mixed order?

views.py

def matesmain(request):
    if request.user.has_posts():
        action = Mates.objects.filter(categories='action')
        sports = Mates.objects.filter(categories='sports')
        
        context = {
            'action' : action,
            'sports' : sports,
        }
        print("nice3")
        return render(request, 'mates.html', context)

mates.html

{% for act in action %}
    {% if act %}
        I have the posts from action category here
    {% endif %}
{% endfor %}
{% for sprt in sports %}
    {% if sprt %}
        I have the posts from sports categpry here
    {% endif %}
{% endfor %}
2 Answers

You can make use of the __in lookup [Django-doc] to otain the Mates objects that belong to any of the categories:

def matesmain(request):
    if request.user.has_posts():
        mates = Mates.objects.filter(
            categories__in=['action', 'sports']
        )
        context = {
            'mates' : mates
        }
        return render(request, 'mates.html', context)
    else:
        # …

You can then render these with:

{% for mate in mates %}
    {{ mate.categories }}
{% endfor %}

You can make use of .order_by('?') [Django-doc] to obtain the items in random order:

def matesmain(request):
    if request.user.has_posts():
        mates = Mates.objects.filter(
            categories__in=['action', 'sports']
        ).order_by('?')
        context = {
            'mates' : mates
        }
        return render(request, 'mates.html', context)
    else:
        # …

An easy way is to assign another variable to each then pass the new variable into context and that will always shuffle them.

def matesmain(request):
    if request.user.has_posts():
        action = Mates.objects.filter(categories='action')
        new_action = action.order_by('?')
        sports = Mates.objects.filter(categories='sports')
        new_sports = sports.order_by('?')
        
        context = {
            'action' : new_action,
            'sports' : new_sports,
        }
        print("nice3")
        return render(request, 'mates.html', context)
Related