Фильтрация с помощью 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>