如何根据以前的查询集结果进行筛选Django
目前,我在同一页面上有两个单独的查询集,它们彼此独立地呈现 Q1=用户 Q2=f Q1返回用户发布的radius request.POST中的所有用户 Q2返回django_filters.FilterSet,具体取决于所选过滤器的头发颜色、年龄等。获取 Q2应该只过滤Q1的结果。我想保持它在同一页上,而不是重定向到不同的网址 如果有人能解释一下最简单的方法,我将不胜感激 views.py如何根据以前的查询集结果进行筛选Django,django,django-views,django-filter,Django,Django Views,Django Filter,目前,我在同一页面上有两个单独的查询集,它们彼此独立地呈现 Q1=用户 Q2=f Q1返回用户发布的radius request.POST中的所有用户 Q2返回django_filters.FilterSet,具体取决于所选过滤器的头发颜色、年龄等。获取 Q2应该只过滤Q1的结果。我想保持它在同一页上,而不是重定向到不同的网址 如果有人能解释一下最简单的方法,我将不胜感激 views.py class ConnectView(View): template_name = 'connect
class ConnectView(View):
template_name = 'connect/home.html'
def get(self, request, *args, **kwargs):
filter = ProfileFilter(request.GET.getlist('filter'))
context = {
'users': User.objects.exclude(username=request.user),
'filter': filter
}
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
if 'latitude' in request.POST and 'longitude' in request.POST:
try:
location = Location(latitude=request.POST['latitude'], longitude=request.POST['longitude'], user = request.user)
location.save()
except:
return JsonResponse({'message': 'location already stored!'})
if 'radius' in request.POST:
radius_km = request.POST.get('radius', 0)
queryset = User.objects.annotate(
radius_sqr=pow(models.F('loc__latitude') -
request.user.loc.latitude, 2) + pow(models.F('loc__longitude') -
request.user.loc.longitude, 2)
).filter(
radius_sqr__lte=pow(int(radius_km) / 9, 2)
).exclude(username=request.user)
filter = ProfileFilter(request.POST, queryset=queryset)
messages.success(request, f'See the results of your search below.')
return render(request, self.template_name)
else:
return render(request, self.template_name)
过滤器.py
class ProfileFilter(django_filters.FilterSet):
class Meta:
model = Profile
fields = {
'age': ['exact'],
'interest': ['exact'],
}
connecthome.html
<form method="POST">
{% csrf_token %}
<h4>Enter a Distance.</h4>
<input type="number" name="radius">
{{ filter.form|crispy }}
<button type="submit">Search.</button>
</form>
{% if filter %}
{% for profile in filter %}
<h5>{{ profile.user.first_name }}</h5>
<p>{{ profile.age }}</p>
{% empty %}
<h1>No results, try again?</h1>
{% endfor %}
{% else %}
{% for user in users %}
<h5>{{ user.first_name }}</h5>
<p>{{ user.profile.age }}</p>
{% empty %}
<h1>No results, try again?</h1>
{% endfor %}
{% endif %}
您应该将模板更改为只有一个表单同时发布radius和过滤器。然后在post方法中,使用位置/半径创建传递给过滤器的查询集:
def post(self, request, *args, **kwargs):
# default queryset, users is needed in context based on your get() method
users = User.objects.exclude(username=request.user.username)
queryset = Profile.objects.exclude(user=request.user)
if 'latitude' in request.POST and 'longitude' in request.POST:
# code to store Location
if 'radius' in request.POST:
radius_km = request.POST.get('radius', 0)
# reduce queryset by users within radius
queryset = queryset.annotate(
radius_sqr=pow(models.F('user__loc__latitude') -
request.user.loc.latitude, 2) + pow(models.F('user__loc__longitude') -
request.user.loc.longitude, 2)
).filter(
radius_sqr__lte=pow(int(radius_km) / 9, 2)
)
messages.success(request, f'See the results of your search below.')
filter = ProfileFilter(request.POST, queryset=queryset)
return render(request, self.template_name, {'filter': filter, 'users': users})
该页面是作为GET请求或POST请求的结果返回的,不能同时返回两者。将所有内容放在一个表单中,并使用GET或POST将所有信息提交到过滤器选择和距离。可能GET更合适,因为您没有向数据库写入任何内容。是的,我确实查找了它,发现我无法将两个请求合并起来。好的,谢谢您的帮助,我非常感谢。如何将filters.py django_filters和forms.py中的radius queryset组合在一起?将radius queryset从POST方法传递到过滤器,从request.get而不是request.POST中获取radius。因此,您的意思是可以将radius queryset传递到filters.py,然后它将呈现一个过滤器集并进行处理按请求。是否与当前的其他筛选器信息相同?您能告诉我将radius queryset传递给filters.py是什么样子吗?我的意思是将您现在在post中的代码移动到get方法并完全删除post,很抱歉,我的评论中没有明确说明。因此,首先检查radius,根据radius是否在请求中构建查询集。获取,然后使用该查询集使用筛选器筛选用户。好的,最后一个问题,即使使用.excludeusername=request.user,也不会将当前用户从结果中排除。为什么需要该行?如果我有{'filter':f}在get方法中?在get中,你在我的帖子中调用了变量f,我称之为filter,我从不使用像f这样的变量名,因为它们没有任何意义。没关系。抱歉,这里有点不正确,传递给ProfileFilter的queryset应该在Profile对象上。配置文件与用户的关系如何?对不起,我指的是整行queryset=users=User.objects.excludeusername=request.User