如何在 Django 中使用 Ajax 对列表视图进行排序?
Posted
技术标签:
【中文标题】如何在 Django 中使用 Ajax 对列表视图进行排序?【英文标题】:How to sort list view using Ajax in Django? 【发布时间】:2020-10-07 07:46:00 【问题描述】:在列表视图模板中,我创建了一个过滤器表单来过滤帖子,它们也是一个排序下拉列表来对它们进行排序:
<form id="sortForm">
<select class="input-text" id="sort" onchange="document.querySelector('#sortSubmitBtn').click()" name="sort"
id="sort">
<option disabled selected>Sort by</option>
<option value="price_l2h" % if 'price_l2h' == values.sort % selected % endif %>
Price (low to high)</option>
<option value="price_h2l" % if 'price_h2l' == values.sort % selected % endif %>
Price (high to low)</option>
</select>
% if values.keywords %
<input type="hidden" name="keywords" id="keywords" value=" values.keywords ">
% endif %
% if values.mls_number %
<input type="hidden" name="mls_number" id="mls_number" value=" values.mls_number ">
% endif %
<button type="submit" id="sortSubmitBtn" style="display: none;">Submit</button>
</form>
这是我用来排序的 Ajax,但它不起作用。我使用相同的 Ajax 语法在模型中保存数据,它工作得很好,但是这个不起作用。
<script>
$(document).on('submit', '#sortForm', function (e)
e.preventDefault();
$.ajax(
type: 'GET',
url: "% url 'listing:search' %",
data:
sort: $('#sort').val(),
keywords: $('#keywords').val(),
mls_number: $('#mls_number').val(),
csrfmiddlewaretoken: " csrf_token ",
,
success: function ()
alert('Form submitted successfully!!');
)
)
</script>
urls.py
:
path('search/', search, name='search'),
谢谢你,我希望有人能帮我解决这个问题。
编辑:这是 GUI 的外观,选择时我希望它对列表进行排序:
编辑:views.py 添加了
def search(request):
queryset = Listing.objects.all().order_by('listing_date')
listing_for = request.GET.get('listing_for')
# filter by price
min_price = request.GET.get('min_price')
max_price = request.GET.get('max_price')
if min_price and max_price:
queryset = queryset.filter(price__range=(min_price, max_price))
# Filter by new mls number
mls_number = request.GET.get('mls_number')
if mls_number:
queryset = queryset.filter(mls_number__exact=mls_number)
# filter by keyword
keywords = request.GET.get('keywords')
if keywords:
queryset = queryset.filter(Q(description__icontains=keywords) | Q(
lot_feature__title__icontains=keywords) | Q(interior_feature__title__icontains=keywords) | Q(exterior_finish__title__icontains=keywords) | Q(extra_feature__title__icontains=keywords) | Q(appliances__title__icontains=keywords) | Q(view__title__icontains=keywords)).distinct()
# sorting function
sort_by = request.GET.get('sort')
if sort_by:
if sort_by == 'price_l2h':
queryset = queryset.order_by('price')
elif sort_by == 'price_h2l':
queryset = queryset.order_by('-price')
elif sort_by == 'newest':
queryset = queryset.order_by('-listing_date')
elif sort_by == 'bedrooms':
queryset = queryset.order_by('-bedrooms')
elif sort_by == 'bathrooms':
queryset = queryset.order_by('-bathrooms')
elif sort_by == 'sqrft':
queryset = queryset.order_by('-sqrft')
context =
'listings': queryset,
'city': city,
'provinces': provinces,
'prices': prices,
'property_types': property_type,
'rooms': rooms,
'values': request.GET,
'int_values': int_values,
'page': page,
return render(request, 'listing/listings.html', context)
【问题讨论】:
有什么错误吗?您也可以添加您的视图,它是如何不起作用的? 没有错误,列表按预期过滤,但我不希望刷新页面,因为我使用的是 Ajax。为什么 Ajax 在这里不起作用 【参考方案1】:假设您有下表:
<select name="orderby" class="form-control" id="sort">
<option value="default" selected="selected">Default sorting</option>
<option value="rating" name ="rating">Sort by average rating</option>
<option value="date" name ="date">Sort by latest</option>
<option value="price-low" name ="price-low">Sort by price: low to high</option>
<option value="price-high" name ="price-high">Sort by price: high to low</option>
</select>
我们从 select 中选择 id 属性并从 Ajax 中提取数据值。
$(document).ready(function()
$('#sort').on('change', function()
var sortid = $('#sort').val();
$.ajax(
type: 'POST',
url: $(this).data('url'),
datatype: 'json',
data: 'sortid': sortid
).done(function (data)
$('.product-wrapper').html(data.sort_by_choice);
);
);
这里,当#sort id 的值改变时,我们将该值分配给变量sortid。
我们正在通过 Ajax 将数据传递到服务器。
我用过POST方法,如果我们不定义方法,默认方法是GET。我正在分配当前 URL,我们也只能分配直接 URL。例如:网址:shop/,
我们的数据类型是JSON,数据是从变量中获取的数据。
现在让我们在下面创建我们的views.py:
def products(request):
products = Products.objects.all().order_by('created_at')
if request.is_ajax() or request.method == 'POST':
sort_parameter = request.POST.get('sortid')
if sort_parameter == 'price-high':
products = products.order_by('price')
elif sort_parameter == 'price-low':
products = products.order_by('-price')
elif sort_parameter == 'date':
products = products.order_by('-created_at')
products = render_to_string(
template_name="shop.html",
context =
'products': products,
)
json_sort = "sort_by_choice": products
return JsonResponse(data=json_sort, safe=False)
return render(request, 'ecommerce/shop.html', 'products': products)
这里如果请求是 ajax,我从 POST get 方法中获取 sort_parameter。如果您在 javascript 文件中的类型是 GET,则我的帖子类型是 POST,您需要通过 GET 方法获取。
之后,
我已经循环排序参数并将参数呈现为字符串。我们需要 render_to_string 因为它会加载一个模板并立即调用它的 render() 方法。
在此之后,我们需要为 AJAX 请求返回 JsonResponse。
如果请求不是 AJAX,则返回常规响应。
加载 JsonResponse 和 render_to_string 导入:
from django.template.loader import render_to_string
from django.http import JsonResponse
【讨论】:
【参考方案2】:ajax 不是这样工作的,你需要发送一个 JsonResponse 并操作它。对于这种操作,您可以使用django-rest-framework
,这将使您的工作更简单。如果您不想使用它,则必须修改类似于此的代码
link.
【讨论】:
【参考方案3】:要在服务器端对数据进行排序,您可以使用 QuerySet 的 order_by-method 或 Model 的 ordering-Meta-option。
您还可以在客户端用 JavaScript 对返回的数据进行排序。
【讨论】:
我知道如何排序,功能正常。这里怎么应用Ajax,为什么Ajax不行? @ytsejam 说你需要发送一个 JsonResponse。 this answer 很好地解释了如何做到这一点。以上是关于如何在 Django 中使用 Ajax 对列表视图进行排序?的主要内容,如果未能解决你的问题,请参考以下文章
通过jQuery ajax调用将值列表传递给django视图