如何格式化 Django URL,以便 AJAX 调用将获取不依赖于当前页面但来自表单值的数据库数据?
Posted
技术标签:
【中文标题】如何格式化 Django URL,以便 AJAX 调用将获取不依赖于当前页面但来自表单值的数据库数据?【英文标题】:How do I format Django URL so that AJAX call will get database data that is not dependent on the current page, but from a form value? 【发布时间】:2021-12-27 12:23:38 【问题描述】:我有一个页面详细介绍了一篇文章和该文章上的 cmets。这个页面的pk是post pk。我希望能够仅使用符号来构造 cmets。我有一系列符号保存到数据库中,它们都与类别类相关联。我的页面上有一个可以选择其中一个类别的表单,但是如何获得 AJAX 调用以加载该类别中的所有符号?用户将需要能够在类别之间进行切换和更改,因此我想使用 AJAX 来执行此操作,而不是每次都重新加载页面。到目前为止,我得到的只是404,而不是founds。我想这样做,以便我可以拖动或选择要添加到 cmets 的符号。我尝试了许多不同的格式来使 URL 正常工作(urls.py
和 main.js
),所以我无法列出我尝试过的所有替代方案,因为这有点让人不知所措。我还在这里和其他网站上阅读了一堆问题,但似乎没有什么与我想要做的事情相匹配。任何帮助将不胜感激。
符号保存在media/uploads/symbol_files/
符号通过模型与 cmets 具有多对多的关系。所有这一切都很好,所以我没有在下面包含它。 目前模板已设置为使用所选类别中的符号填充第二个表单,稍后我将更改此设置,为了方便起见,我只是这样设置。
这是终端输出的示例:
Not Found: /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);
);
);
【问题讨论】:
【参考方案1】:需要的网址
'<int:pk>/'get_symbols'/<int:id>/'
还有一些其他错误需要修复。
【讨论】:
以上是关于如何格式化 Django URL,以便 AJAX 调用将获取不依赖于当前页面但来自表单值的数据库数据?的主要内容,如果未能解决你的问题,请参考以下文章