kopia lustrzana https://github.com/wagtail/wagtail
Use logical OR operator to combine search fields for Django ORM in IndexView
rodzic
de70673bee
commit
d737f29a62
docs/releases
wagtail
admin
tests/viewsets
views/generic
test/testapp
|
@ -32,6 +32,7 @@ Changelog
|
|||
* Fix: Add a fallback background for the editing preview iframe for sites without a background (Ian Price)
|
||||
* Fix: Remove search logging from project template so that new projects without the search promotions module will not error (Matt Westcott)
|
||||
* Fix: Ensure text only email notifications for updated comments do not escape HTML characters (Rohit Sharma)
|
||||
* Fix: Use logical OR operator to combine search fields for Django ORM in generic IndexView (Varun Kumar)
|
||||
* Docs: Fix code example for `{% picture ... as ... %}` template tag (Rezyapkin)
|
||||
|
||||
|
||||
|
|
|
@ -763,6 +763,7 @@
|
|||
* Marcel Kornblum
|
||||
* Cameron Lamb
|
||||
* Sam Dudley
|
||||
* Varun Kumar
|
||||
|
||||
## Translators
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ depth: 1
|
|||
* Add a fallback background for the editing preview iframe for sites without a background (Ian Price)
|
||||
* Remove search logging from project template so that new projects without the search promotions module will not error (Matt Westcott)
|
||||
* Ensure text only email notifications for updated comments do not escape HTML characters (Rohit Sharma)
|
||||
* Use logical OR operator to combine search fields for Django ORM in generic IndexView (Varun Kumar)
|
||||
|
||||
### Documentation
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ from wagtail.models import ModelLogEntry
|
|||
from wagtail.test.testapp.models import (
|
||||
FeatureCompleteToy,
|
||||
JSONStreamModel,
|
||||
SearchTestModel,
|
||||
VariousOnDeleteModel,
|
||||
)
|
||||
from wagtail.test.utils.template_tests import AdminTemplateTestUtils
|
||||
|
@ -452,6 +453,44 @@ class TestSearchIndexResultsView(TestSearchIndexView):
|
|||
pass
|
||||
|
||||
|
||||
class TestSearchFields(WagtailTestUtils, TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
objects = [
|
||||
SearchTestModel(title="Hello World", body="This one is classic"),
|
||||
SearchTestModel(title="Hello Anime", body="We love anime (opinions vary)"),
|
||||
SearchTestModel(title="Food", body="I like food, do you?"),
|
||||
]
|
||||
SearchTestModel.objects.bulk_create(objects)
|
||||
|
||||
def setUp(self):
|
||||
self.login()
|
||||
|
||||
def get(self, q):
|
||||
return self.client.get(reverse("searchtest:index"), {"q": q})
|
||||
|
||||
def test_single_result_with_body(self):
|
||||
response = self.get("IkE")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertNotContains(response, "Hello World")
|
||||
self.assertNotContains(response, "Hello Anime")
|
||||
self.assertContains(response, "Food")
|
||||
|
||||
def test_multiple_results_with_title(self):
|
||||
response = self.get("ELlo")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, "Hello World")
|
||||
self.assertContains(response, "Hello Anime")
|
||||
self.assertNotContains(response, "Food")
|
||||
|
||||
def test_no_results(self):
|
||||
response = self.get("Abra Kadabra")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertNotContains(response, "Hello World")
|
||||
self.assertNotContains(response, "Hello Anime")
|
||||
self.assertNotContains(response, "Food")
|
||||
|
||||
|
||||
class TestListExport(WagtailTestUtils, TestCase):
|
||||
def setUp(self):
|
||||
self.user = self.login()
|
||||
|
|
|
@ -9,6 +9,7 @@ from django.core.exceptions import (
|
|||
PermissionDenied,
|
||||
)
|
||||
from django.db import models, transaction
|
||||
from django.db.models import Q
|
||||
from django.db.models.functions import Cast
|
||||
from django.forms import Form
|
||||
from django.http import Http404, HttpResponseRedirect
|
||||
|
@ -295,12 +296,10 @@ class IndexView(
|
|||
return search_backend.search(
|
||||
self.search_query, queryset, fields=self.search_fields
|
||||
)
|
||||
|
||||
filters = {
|
||||
field + "__icontains": self.search_query
|
||||
for field in self.search_fields or []
|
||||
}
|
||||
return queryset.filter(**filters)
|
||||
query = Q()
|
||||
for field in self.search_fields or []:
|
||||
query |= Q(**{field + "__icontains": self.search_query})
|
||||
return queryset.filter(query)
|
||||
|
||||
def _get_title_column(self, field_name, column_class=TitleColumn, **kwargs):
|
||||
if not issubclass(column_class, ButtonsColumnMixin):
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
# Generated by Django 4.2.7 on 2023-11-08 14:46
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("tests", "0030_purgerevisionsprotectedtestmodel"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="SearchTestModel",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("title", models.CharField(max_length=255)),
|
||||
("body", models.TextField()),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -2177,3 +2177,15 @@ class PurgeRevisionsProtectedTestModel(models.Model):
|
|||
revision = models.OneToOneField(
|
||||
"wagtailcore.Revision", on_delete=models.PROTECT, related_name="+"
|
||||
)
|
||||
|
||||
|
||||
class SearchTestModel(models.Model):
|
||||
title = models.CharField(max_length=255)
|
||||
body = models.TextField()
|
||||
panels = [
|
||||
FieldPanel("title"),
|
||||
FieldPanel("body"),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
|
|
@ -24,6 +24,7 @@ from wagtail.test.testapp.models import (
|
|||
JSONMinMaxCountStreamModel,
|
||||
JSONStreamModel,
|
||||
ModelWithStringTypePrimaryKey,
|
||||
SearchTestModel,
|
||||
)
|
||||
|
||||
|
||||
|
@ -196,6 +197,12 @@ class JSONModelViewSetGroup(ModelViewSetGroup):
|
|||
)
|
||||
|
||||
|
||||
class SearchTestModelViewSet(ModelViewSet):
|
||||
model = SearchTestModel
|
||||
search_fields = ["title", "body"]
|
||||
form_fields = ["title", "body"]
|
||||
|
||||
|
||||
class FeatureCompleteToyViewSet(ModelViewSet):
|
||||
model = FeatureCompleteToy
|
||||
url_namespace = "feature_complete_toy"
|
||||
|
|
|
@ -35,6 +35,7 @@ from wagtail.test.testapp.models import (
|
|||
from wagtail.test.testapp.views import (
|
||||
JSONModelViewSetGroup,
|
||||
MiscellaneousViewSetGroup,
|
||||
SearchTestModelViewSet,
|
||||
ToyViewSetGroup,
|
||||
animated_advert_chooser_viewset,
|
||||
)
|
||||
|
@ -242,7 +243,11 @@ def add_broken_links_summary_item(request, items):
|
|||
|
||||
@hooks.register("register_admin_viewset")
|
||||
def register_viewsets():
|
||||
return [MiscellaneousViewSetGroup(), JSONModelViewSetGroup()]
|
||||
return [
|
||||
MiscellaneousViewSetGroup(),
|
||||
JSONModelViewSetGroup(),
|
||||
SearchTestModelViewSet(name="searchtest"),
|
||||
]
|
||||
|
||||
|
||||
@hooks.register("register_admin_viewset")
|
||||
|
|
Ładowanie…
Reference in New Issue