Как мне отформатировать django url так, чтобы вызов AJAX получал данные базы данных, не зависящие от текущей страницы, а от значения формы?
У меня есть страница, на которой подробно описывается пост и комментарии к нему. Пк для этой страницы - это пк поста. Я хочу иметь возможность создавать комментарии, используя только символы. У меня есть ряд символов, сохраненных в базе данных, которые все связаны с классом категории. У меня есть форма на странице, в которой можно выбрать одну из этих категорий, но как мне получить вызов AJAX для загрузки всех символов в этой категории? Пользователь должен иметь возможность менять категории местами, поэтому я хочу сделать это с помощью AJAX, а не перезагружать страницу каждый раз. Пока все, что я получаю, это 404 not founds. Я хочу сделать так, чтобы я мог перетаскивать или выбирать символы для добавления в комментарии. Я пробовал множество различных форматов, чтобы заставить урлы работать (как в urls.py, так и в main.js), поэтому я не могу перечислить все альтернативы, которые я пробовал, так как все это немного перегружено. Я также прочитал кучу вопросов на этом и других сайтах, но ничего не похоже на то, что я пытаюсь сделать. Любая помощь будет принята с благодарностью.
Символы сохраняются в media/uploads/symbol_files/
Символы имеют отношения "многие-ко-многим" с комментариями со сквозной моделью. Все это работает нормально, поэтому я не стал включать это ниже. На данный момент шаблон настроен на заполнение второй формы символами из выбранной категории, я изменю это позже, я просто сделал это так для удобства.
Вот пример вывода из терминала:
Не найдено: /posts/1/get_symbols/Alphabet
Где "Алфавит" - это название одной из категорий.
models.py:
class SymbolCategory(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
def get_symbols(self):
return self.symbol_set.all()
class Meta:
verbose_name = "SymbolCategory"
verbose_name_plural = "SymbolCategories"
class Symbol(models.Model):
name = models.CharField(max_length=50)
image = models.FileField(upload_to='uploads/symbol_files')
category = models.ForeignKey(SymbolCategory, on_delete=models.CASCADE)
def __str__(self):
return f'{self.name}-{self.pk}'
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length = 100)
body = models.TextField(max_length = 500)
video_file = models.FileField(blank=True, upload_to='uploads/video_files', validators = [FileExtensionValidator(allowed_extensions=['mp4', 'webm'])])
thumbnail = models.FileField(blank=True, upload_to='uploads/thumbnails', validators = [FileExtensionValidator(allowed_extensions=['png', 'jpg','jpeg'])])
date_posted = models.DateTimeField(default=timezone.now)
category = models.ForeignKey(PostCategory,blank=True, on_delete=models.CASCADE)
class Meta:
verbose_name_plural = "Posts"
views.py:
class DetailPost(View):
def get(self, request, pk, *args, **kwargs):
post = Post.objects.get(pk=pk)
symbol_comments = SymbolComment.objects.filter(post=post).order_by('-created_on')
categories = SymbolCategory.objects.all()
form_comment = CommentForm()
symbol_get_form = SymbolGetForm()
context = {
'object': post,
'form_comment': form_comment,
'symbol_comments': symbol_comments,
'symbol_get_form': symbol_get_form,
'categories': categories,
}
return render(request, 'posts/detail_post.html', context)
def post(self, request, pk, *args, **kwargs):
post = Post.objects.get(pk=pk)
form_comment = CommentForm(request.POST)
if form_comment.is_valid():
symbol_comments = SymbolComment(
user = self.request.user,
post = post
)
symbol_comments.save()
symbol_comments = SymbolComment.objects.filter(post=post).order_by('-created_on')
context = {
'object': post,
'form_comment': form_comment,
'symbol_comments': symbol_comments,
}
return render(request, 'posts/detail_post.html', context)
def get_symbols(request):
if request.is_ajax():
if request.method == "POST": # I've tried with GET but it doesn't work either, at the moment it currently has POST but I think this is wrong.
category_name = request.POST['category_name']
print(category_name)
try:
category = SymbolCategory.objects.filter(id = category_name).first()
symbols = Symbol.objects.filter(category = category)
except Exception:
data['error_message'] = 'error'
return JsonResponse(data)
return JsonResponse(list(symbols.values('name', 'image_field')), safe = False)
urls.py:
urlpatterns = [
path('<int:pk>/', DetailPost.as_view(), name='detail-post'),
path('get_symbols/', get_symbols, name='get-symbols'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Шаблон:
{% csrf_token %}
<div class="col-md-6">
<div class="form-group">
<label for="inputStatus">Category</label>
<select id="select-category" class="form-control-sm custom-select">
<option selected disabled>Choose a symbol category</option>
{% for category in categories %}
<option value="{{category.name}}">{{category.name}}</option>
{% endfor %}
</select>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="inputStatus">Symbol</label>
<select id="category-symbol" class="form-control-sm custom-select" name="symbol">
<option selected disabled>Choose a symbol</option>
</select>
</div>
</div>
main.js:
$("#select-category").change(function () {
const categoryName = $(this).val();
$.ajax({
type: "POST",
url: `get_symbols/${categoryName}`,
data: {
'category_name': categoryName,
'csrfmiddlewaretoken':$('input[name=csrfmiddlewaretoken]').val(),
},
success: function (data) {
let html_data = '<option value="">---------</option>';
data.forEach(function (data) {
html_data += `<option value="${data.id}">${data.name}</option>`
});
console.log(data)
$("#category-symbol").html(html_data);
}
});
});
Урл должен быть
'<int:pk>/'get_symbols'/<int:id>/'
Были и несколько других ошибок, которые требовали исправления.