我知道在搜索时不能直接使用外键上的包含,但我还没有找到解决方案。
这是我在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
author
是User
对象。因此,您应该使用username
、first_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]引用用户模型,而不是使用User
model[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