使用django外键进行多次搜索(相关字段查找无效:iconcontains)



我知道在搜索时不能直接使用外键上的包含,但我还没有找到解决方案。

这是我在views.py中的搜索视图(我已经导入了所需的每个模型):

def search(request):
# if the user actually fills up the form
if request.method == "POST":
searched = request.POST['searched']
# author__icontains part is not working
posts = Post.objects.filter(Q(title__icontains=searched) | Q(author__author__icontains=searched))
return render(request, 'blog/search.html', {'searched': searched, 'posts': posts})
else:
return render(request, 'blog/search.html', {})

下面是我在model.py中的模型:


class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})

主要,这不是工作:

posts = Post.objects.filter(Q(title__icontains=searched) | Q(author__author__icontains=searched))

错误是Related Field got invalid lookup: icontains

authorUser对象。因此,您应该使用usernamefirst_name或其他字段。可能author也是a的值related_name=…[Django-doc],因此在另一个表上创建LEFT OUTER JOIN,从而可以在该表的主键上工作。

因此,您可以使用: 进行过滤。
def search(request):
# if the user actually fills up the form
if request.method == 'POST':
searched = request.POST['searched']
# author__icontains part is not working
posts = Post.objects.filter(
Q(title__icontains=searched) |
Q(author__username__icontains=searched)
)
return render(request, 'blog/search.html', {'searched': searched, 'posts': posts})
return render(request, 'blog/search.html')

注意:通常最好使用settings.AUTH_USER_MODEL[Django-doc]引用用户模型,而不是使用Usermodel[Django-doc]要了解更多信息,您可以查看参考User模型部分的文档。


注意:搜索通常通过GET请求完成,因为这意味着查询存储在querystring中,因此存储在URL中。这样可以方便地将查询的URL分享给其他人,或者将结果加入书签。POST请求通常用于状态更改操作,或者用于具有敏感数据的请求。

这个问题是由于Django无法处理一个字段中有多个值的外键。这个限制的原因是Django不知道如何解决这些冲突,所以它只是忽略它们。在你的例子中,因为你的模型中有两个字段匹配搜索条件,Django会忽略这两个结果,并显示一个空列表。

要解决这个问题,我们需要为模型添加一个名为"icontains"的新属性。它将包含另一个字段的值。然后,我们将这个属性设置为"作者"的默认值。字段。下面是你的模型现在的样子:

class Post(models.Model): title = models.CharField(max_length=100) content = models.TextField() date_posted = models.DateTimeField(default=timezone.now) author = models.ForeignKey(User, on_delete=models.CASCADE) icontains = models.CharField(max_length=100, null=True, blank=True) def __str__(self): return self.title def get_absolute_url(self): return reverse('post-detail', kwargs=dict(pk=self.pk))

修改后,代码将正常工作。

有关此限制的更多信息,请参阅Django文档:https://docs.djangoproject.com/en/1.9/topics/db/queries/#lookups-that-span-relationships

最新更新