Как мне отформатировать 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>/'

Были и несколько других ошибок, которые требовали исправления.

Вернуться на верх