Use logical OR operator to combine search fields for Django ORM in IndexView

pull/11000/head
varun kumar 2023-10-04 21:58:15 +05:30 zatwierdzone przez Sage Abdullah
rodzic de70673bee
commit d737f29a62
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: EB1A33CC51CC0217
9 zmienionych plików z 101 dodań i 7 usunięć

Wyświetl plik

@ -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)

Wyświetl plik

@ -763,6 +763,7 @@
* Marcel Kornblum
* Cameron Lamb
* Sam Dudley
* Varun Kumar
## Translators

Wyświetl plik

@ -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

Wyświetl plik

@ -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()

Wyświetl plik

@ -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):

Wyświetl plik

@ -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()),
],
),
]

Wyświetl plik

@ -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

Wyświetl plik

@ -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"

Wyświetl plik

@ -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")