Фильтрация с помощью AJAX в Django

В моем проекте Django есть базовое представление, в которое я передаю все экземпляры модели Article, а затем отображаю их в шаблоне HTML с помощью цикла for. У меня также есть модель Topic, поэтому я отображаю все темы в виде кнопок, также с помощью цикла for. Моя цель - отфильтровать статьи по нажатию определенной кнопки Topic, так что если я нажму, например, "Политика", то вместо всех статей будут отображены только статьи, связанные с темой "Политика". Я хочу использовать для этого AJAX-запрос, но у меня нет опыта работы с ним, поэтому у меня возникают некоторые проблемы с тем, как достичь своей цели.

Вот мое представление. Я пытаюсь сделать AJAX в том же представлении, но я не уверен, что это правильно, потому что в большинстве случаев, которые я видел, было создано отдельное представление:

def main_view(request):
    all_articles = Article.objects.all()[::-1]
    top_articles = all_articles[:10]
    topics = Topic.objects.all()
    if request.is_ajax():
        topic_name = request.GET.get('topic_name')
        all_articles = Article.objects.filter(topics=topic_name)
        return JsonResponse({'all_articles': all_articles})

    return render(request, "mainapp/main_refactor.html", {"all_articles": all_articles, "top_articles": top_articles, "topics": topics})

Упрощенный HTML-шаблон:

{% for topic in topics %}
    <button class="topic-button" data-url="{% url 'mainapp:filter_articles' topic.name %}"
            data-topic-name="{{ topic.name }}">{{ topic.name }}</button>
{% endfor %}
<section id="article-list" class="new-articles">
    {% for article in all_articles %}
        {{ article.body }}
    {% endfor %}

И код AJAX:

$(document).ready(function () {
    $('.topic-button').click(function () {
        var topicName = $(this).data('topic-name');
        var url = $(this).data('url');  // tried to add separate URLs for each Topic filtering, but abandoned it for now, so everything is in one view
        console.log(url);
        $.ajax({
            url: '',
            method: 'GET',
            data: {'topic_name': topicName},
            success: function (response) {
                console.log(response + " I have no idea what to code here");
            },
        });
    });
});

Приведенный выше код - это то, на чем я сейчас нахожусь. Было бы идеально иметь отдельный вид для ajax запроса с url "/topic/str:topic_name". Заранее спасибо за помощь.

У вас должна быть отдельная конечная точка для фильтра

def filter_articles(request):
    topic_name = request.GET.get('topic_name')
    if topic_name:
        articles = Article.objects.filter(topics__name=topic_name)
        return JsonResponse({'all_articles': articles})  # Serialize articles for JSON response
    else:
        return JsonResponse({'error': 'No topic provided'})

Url

path('filter_articles/', views.filter_articles, name='filter_articles')

Для html-части вы можете сделать это следующим образом

{% for topic in topics %}
    <button class="topic-button" data-topic-name="{{ topic.name }}">{{ topic.name }}</button>
{% endfor %}
<section id="article-list" class="new-articles">
    </section>

<script>
$(document).ready(function () {
    $('.topic-button').click(function () {
        var topicName = $(this).data('topic-name');
        $.ajax({
            url: '{% url 'mainapp:filter_articles' %}', // Use reverse URL lookup
            method: 'GET',
            data: {'topic_name': topicName},
            success: function (response) {
                if (response.error) {
                    console.error(response.error);
                    return;
                }
                // Here's an example
                $('#article-list').empty();  // Clear the current articles
                response.all_articles.forEach(function(article) {
                  $('#article-list').append('<div>' + article.body + '</div>');
            });
            },
        });
    });
});
</script>
Вернуться на верх