django-searchkit 1.1__py3-none-any.whl → 1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. build/lib/build/lib/build/lib/build/lib/example/example/__init__.py +0 -0
  2. build/lib/build/lib/build/lib/build/lib/example/example/admin.py +16 -0
  3. build/lib/build/lib/build/lib/build/lib/example/example/asgi.py +16 -0
  4. build/lib/build/lib/build/lib/build/lib/example/example/management/__init__.py +0 -0
  5. build/lib/build/lib/build/lib/build/lib/example/example/management/commands/__init__.py +0 -0
  6. build/lib/build/lib/build/lib/build/lib/example/example/management/commands/createtestdata.py +62 -0
  7. build/lib/build/lib/build/lib/build/lib/example/example/migrations/0001_initial.py +48 -0
  8. build/lib/build/lib/build/lib/build/lib/example/example/migrations/__init__.py +0 -0
  9. build/lib/build/lib/build/lib/build/lib/example/example/models.py +38 -0
  10. build/lib/build/lib/build/lib/build/lib/example/example/settings.py +125 -0
  11. build/lib/build/lib/build/lib/build/lib/example/example/urls.py +23 -0
  12. build/lib/build/lib/build/lib/build/lib/example/example/wsgi.py +16 -0
  13. build/lib/build/lib/build/lib/build/lib/searchkit/__init__.py +0 -0
  14. build/lib/build/lib/build/lib/build/lib/searchkit/__version__.py +16 -0
  15. build/lib/build/lib/build/lib/build/lib/searchkit/admin.py +44 -0
  16. build/lib/build/lib/build/lib/build/lib/searchkit/apps.py +6 -0
  17. build/lib/build/lib/build/lib/build/lib/searchkit/filters.py +36 -0
  18. build/lib/build/lib/build/lib/build/lib/searchkit/forms/__init__.py +5 -0
  19. build/lib/build/lib/build/lib/build/lib/searchkit/forms/fields.py +56 -0
  20. build/lib/build/lib/build/lib/build/lib/searchkit/forms/search.py +61 -0
  21. build/lib/build/lib/build/lib/build/lib/searchkit/forms/searchkit.py +177 -0
  22. build/lib/build/lib/build/lib/build/lib/searchkit/forms/utils.py +154 -0
  23. build/lib/build/lib/build/lib/build/lib/searchkit/migrations/0001_initial.py +30 -0
  24. build/lib/build/lib/build/lib/build/lib/searchkit/migrations/0002_rename_searchkitsearch_search.py +18 -0
  25. build/lib/build/lib/build/lib/build/lib/searchkit/migrations/__init__.py +0 -0
  26. build/lib/build/lib/build/lib/build/lib/searchkit/models.py +21 -0
  27. build/lib/build/lib/build/lib/build/lib/searchkit/templatetags/__init__.py +0 -0
  28. build/lib/build/lib/build/lib/build/lib/searchkit/templatetags/searchkit.py +20 -0
  29. build/lib/build/lib/build/lib/build/lib/searchkit/tests.py +400 -0
  30. build/lib/build/lib/build/lib/build/lib/searchkit/urls.py +7 -0
  31. build/lib/build/lib/build/lib/build/lib/searchkit/utils.py +13 -0
  32. build/lib/build/lib/build/lib/build/lib/searchkit/views.py +23 -0
  33. build/lib/build/lib/build/lib/example/example/__init__.py +0 -0
  34. build/lib/build/lib/build/lib/example/example/admin.py +16 -0
  35. build/lib/build/lib/build/lib/example/example/asgi.py +16 -0
  36. build/lib/build/lib/build/lib/example/example/management/__init__.py +0 -0
  37. build/lib/build/lib/build/lib/example/example/management/commands/__init__.py +0 -0
  38. build/lib/build/lib/build/lib/example/example/management/commands/createtestdata.py +62 -0
  39. build/lib/build/lib/build/lib/example/example/migrations/0001_initial.py +48 -0
  40. build/lib/build/lib/build/lib/example/example/migrations/__init__.py +0 -0
  41. build/lib/build/lib/build/lib/example/example/models.py +38 -0
  42. build/lib/build/lib/build/lib/example/example/settings.py +125 -0
  43. build/lib/build/lib/build/lib/example/example/urls.py +23 -0
  44. build/lib/build/lib/build/lib/example/example/wsgi.py +16 -0
  45. build/lib/build/lib/build/lib/searchkit/__init__.py +0 -0
  46. build/lib/build/lib/build/lib/searchkit/__version__.py +16 -0
  47. build/lib/build/lib/build/lib/searchkit/admin.py +44 -0
  48. build/lib/build/lib/build/lib/searchkit/apps.py +6 -0
  49. build/lib/build/lib/build/lib/searchkit/filters.py +36 -0
  50. build/lib/build/lib/build/lib/searchkit/forms/__init__.py +5 -0
  51. build/lib/build/lib/build/lib/searchkit/forms/fields.py +56 -0
  52. build/lib/build/lib/build/lib/searchkit/forms/search.py +61 -0
  53. build/lib/build/lib/build/lib/searchkit/forms/searchkit.py +177 -0
  54. build/lib/build/lib/build/lib/searchkit/forms/utils.py +154 -0
  55. build/lib/build/lib/build/lib/searchkit/migrations/0001_initial.py +30 -0
  56. build/lib/build/lib/build/lib/searchkit/migrations/0002_rename_searchkitsearch_search.py +18 -0
  57. build/lib/build/lib/build/lib/searchkit/migrations/__init__.py +0 -0
  58. build/lib/build/lib/build/lib/searchkit/models.py +21 -0
  59. build/lib/build/lib/build/lib/searchkit/templatetags/__init__.py +0 -0
  60. build/lib/build/lib/build/lib/searchkit/templatetags/searchkit.py +20 -0
  61. build/lib/build/lib/build/lib/searchkit/tests.py +400 -0
  62. build/lib/build/lib/build/lib/searchkit/urls.py +7 -0
  63. build/lib/build/lib/build/lib/searchkit/utils.py +13 -0
  64. build/lib/build/lib/build/lib/searchkit/views.py +23 -0
  65. build/lib/build/lib/example/example/admin.py +1 -1
  66. build/lib/build/lib/searchkit/__version__.py +1 -1
  67. build/lib/build/lib/searchkit/admin.py +15 -1
  68. build/lib/build/lib/searchkit/filters.py +15 -6
  69. build/lib/build/lib/searchkit/forms/fields.py +5 -4
  70. build/lib/build/lib/searchkit/forms/search.py +0 -1
  71. build/lib/build/lib/searchkit/forms/searchkit.py +36 -13
  72. build/lib/build/lib/searchkit/forms/utils.py +50 -74
  73. build/lib/build/lib/searchkit/models.py +0 -6
  74. build/lib/build/lib/searchkit/tests.py +1 -3
  75. build/lib/build/lib/searchkit/utils.py +13 -0
  76. build/lib/build/lib/searchkit/views.py +3 -3
  77. build/lib/example/example/admin.py +1 -1
  78. build/lib/searchkit/__version__.py +1 -1
  79. build/lib/searchkit/admin.py +15 -1
  80. build/lib/searchkit/filters.py +15 -6
  81. build/lib/searchkit/forms/fields.py +5 -4
  82. build/lib/searchkit/forms/search.py +0 -1
  83. build/lib/searchkit/forms/searchkit.py +36 -13
  84. build/lib/searchkit/forms/utils.py +50 -74
  85. build/lib/searchkit/models.py +0 -6
  86. build/lib/searchkit/tests.py +1 -3
  87. build/lib/searchkit/utils.py +13 -0
  88. build/lib/searchkit/views.py +3 -3
  89. {django_searchkit-1.1.dist-info → django_searchkit-1.3.dist-info}/METADATA +1 -1
  90. django_searchkit-1.3.dist-info/RECORD +166 -0
  91. searchkit/__version__.py +1 -1
  92. searchkit/admin.py +15 -1
  93. searchkit/filters.py +15 -6
  94. searchkit/forms/fields.py +5 -4
  95. searchkit/forms/search.py +0 -1
  96. searchkit/forms/searchkit.py +36 -13
  97. searchkit/forms/utils.py +50 -74
  98. searchkit/models.py +0 -6
  99. searchkit/tests.py +1 -3
  100. searchkit/utils.py +13 -0
  101. searchkit/views.py +3 -3
  102. django_searchkit-1.1.dist-info/RECORD +0 -99
  103. {django_searchkit-1.1.dist-info → django_searchkit-1.3.dist-info}/WHEEL +0 -0
  104. {django_searchkit-1.1.dist-info → django_searchkit-1.3.dist-info}/licenses/LICENCE +0 -0
  105. {django_searchkit-1.1.dist-info → django_searchkit-1.3.dist-info}/top_level.txt +0 -0
  106. {django_searchkit-1.1.dist-info → django_searchkit-1.3.dist-info}/zip-safe +0 -0
@@ -1,19 +1,30 @@
1
1
  from django import forms
2
+ from django.apps import apps
3
+ from django.contrib.admin import widgets
4
+ from django.contrib.contenttypes.models import ContentType
2
5
  from django.utils.translation import gettext_lazy as _
3
6
  from django.utils.functional import cached_property
4
7
  from .utils import CssClassMixin, FIELD_PLAN, OPERATOR_DESCRIPTION
5
8
  from .utils import SUPPORTED_FIELDS
6
9
  from .utils import ModelTree
7
10
  from .utils import MediaMixin
8
- from .utils import get_searchable_models
11
+ from .fields import DateRangeField
12
+ from ..utils import is_searchable_model
9
13
 
10
14
 
11
15
  class SearchkitModelForm(forms.Form):
12
16
  """
13
17
  Form to select a content type.
14
18
  """
19
+ def __init__(self, *args, **kwargs):
20
+ super().__init__(*args, **kwargs)
21
+ models = [m for m in apps.get_models() if is_searchable_model(m)]
22
+ ids = [ContentType.objects.get_for_model(m).id for m in models]
23
+ queryset = self.fields['searchkit_model'].queryset.filter(pk__in=ids)
24
+ self.fields['searchkit_model'].queryset = queryset
25
+
15
26
  searchkit_model = forms.ModelChoiceField(
16
- queryset=get_searchable_models(),
27
+ queryset=ContentType.objects.all().order_by('app_label', 'model'),
17
28
  label=_('Model'),
18
29
  empty_label=_('Select a Model'),
19
30
  widget=forms.Select(attrs={
@@ -105,27 +116,19 @@ class BaseSearchkitForm(MediaMixin, CssClassMixin, forms.Form):
105
116
  return choices
106
117
 
107
118
  def _add_field_name_field(self):
108
- initial = self.initial.get('field')
109
119
  choices = self._get_model_field_choices()
110
- field = forms.ChoiceField(label=_('Model field'), choices=choices, initial=initial)
120
+ field = forms.ChoiceField(label=_('Model field'), choices=choices)
111
121
  field.widget.attrs.update({"class": self.reload_on_change_css_class})
112
122
  self.fields['field'] = field
113
123
 
114
124
  def _add_operator_field(self):
115
- initial = self.initial.get('operator')
116
125
  choices = [(o, OPERATOR_DESCRIPTION[o]) for o in self.field_plan.keys()]
117
- field = forms.ChoiceField(label=_('Operator'), choices=choices, initial=initial)
126
+ field = forms.ChoiceField(label=_('Operator'), choices=choices)
118
127
  field.widget.attrs.update({"class": self.reload_on_change_css_class})
119
128
  self.fields['operator'] = field
120
129
 
121
130
  def _add_value_field(self):
122
- initial = self.initial.get('value')
123
- field_class = self.field_plan[self.operator][0]
124
- if getattr(field_class, 'choices', None) and getattr(self.model_field, 'choices', None):
125
- field = field_class(choices=self.model_field.choices, initial=initial)
126
- else:
127
- field = field_class()
128
- self.fields['value'] = field
131
+ self.fields['value'] = self.field_plan[self.operator](self.model_field)
129
132
 
130
133
 
131
134
  class BaseSearchkitFormSet(CssClassMixin, forms.BaseFormSet):
@@ -143,6 +146,26 @@ class BaseSearchkitFormSet(CssClassMixin, forms.BaseFormSet):
143
146
  def get_default_prefix(self):
144
147
  return "searchkit"
145
148
 
149
+ @cached_property
150
+ def uses_date_widget(self):
151
+ """
152
+ Check if the form uses a date widget.
153
+ """
154
+ for form in self.forms:
155
+ for field in form.fields.values():
156
+ if isinstance(field.widget, (widgets.AdminDateWidget, widgets.AdminSplitDateTime)):
157
+ return True
158
+ elif isinstance(field, DateRangeField):
159
+ return True
160
+ return False
161
+
162
+ @cached_property
163
+ def forms(self):
164
+ if self.model:
165
+ return super().forms
166
+ else:
167
+ return []
168
+
146
169
 
147
170
  def searchkit_formset_factory(model, **kwargs):
148
171
  form = type('SearchkitForm', (BaseSearchkitForm,), dict(model=model))
@@ -1,13 +1,9 @@
1
1
  from modeltree import ModelTree as BaseModelTree
2
2
  from collections import OrderedDict
3
- from django.apps import apps
4
- from django.contrib import admin
5
- from django.contrib.contenttypes.models import ContentType
3
+ from django.contrib.admin.widgets import AdminDateWidget, AdminSplitDateTime
6
4
  from django.db import models
7
- from django.db.utils import OperationalError
8
5
  from django import forms
9
6
  from django.utils.translation import gettext_lazy as _
10
- from ..filters import SearchkitFilter
11
7
  from . import fields as searchkit_fields
12
8
 
13
9
 
@@ -50,94 +46,95 @@ FIELD_PLAN = OrderedDict((
50
46
  (
51
47
  lambda f: isinstance(f, models.BooleanField),
52
48
  {
53
- 'exact': (forms.NullBooleanField,),
49
+ 'exact': lambda f: forms.NullBooleanField() if f.null else forms.BooleanField(),
54
50
  }
55
51
  ),
56
52
  (
57
53
  lambda f: isinstance(f, models.CharField) and f.choices,
58
54
  {
59
- 'exact': (forms.ChoiceField,),
60
- 'contains': (forms.CharField,),
61
- 'startswith': (forms.CharField,),
62
- 'endswith': (forms.CharField,),
63
- 'regex': (forms.CharField,),
64
- 'in': (forms.MultipleChoiceField,),
55
+ 'exact': lambda f: forms.ChoiceField(choices=f.choices),
56
+ 'contains': lambda f: forms.CharField(),
57
+ 'startswith': lambda f: forms.CharField(),
58
+ 'endswith': lambda f: forms.CharField(),
59
+ 'regex': lambda f: forms.CharField(),
60
+ 'in': lambda f: forms.MultipleChoiceField(choices=f.choices),
65
61
  }
66
62
  ),
67
63
  (
68
64
  lambda f: isinstance(f, models.CharField),
69
65
  {
70
- 'exact': (forms.CharField,),
71
- 'contains': (forms.CharField,),
72
- 'startswith': (forms.CharField,),
73
- 'endswith': (forms.CharField,),
74
- 'regex': (forms.CharField,),
66
+ 'exact': lambda f: forms.CharField(),
67
+ 'contains': lambda f: forms.CharField(),
68
+ 'startswith': lambda f: forms.CharField(),
69
+ 'endswith': lambda f: forms.CharField(),
70
+ 'regex': lambda f: forms.CharField(),
75
71
  }
76
72
  ),
77
73
  (
78
74
  lambda f: isinstance(f, models.IntegerField) and f.choices,
79
75
  {
80
- 'exact': (forms.ChoiceField,),
81
- 'contains': (forms.IntegerField,),
82
- 'startswith': (forms.IntegerField,),
83
- 'endswith': (forms.IntegerField,),
84
- 'regex': (forms.IntegerField,),
85
- 'in': (forms.MultipleChoiceField,),
76
+ 'exact': lambda f: forms.ChoiceField(choices=f.choices),
77
+ 'gt': lambda f: forms.IntegerField(),
78
+ 'gte': lambda f: forms.IntegerField(),
79
+ 'lt': lambda f: forms.IntegerField(),
80
+ 'lte': lambda f: forms.IntegerField(),
81
+ 'range': lambda f: searchkit_fields.IntegerRangeField(),
82
+ 'in': lambda f: forms.MultipleChoiceField(choices=f.choices),
86
83
  }
87
84
  ),
88
85
  (
89
86
  lambda f: isinstance(f, models.IntegerField),
90
87
  {
91
- 'exact': (forms.IntegerField,),
92
- 'gt': (forms.IntegerField,),
93
- 'gte': (forms.IntegerField,),
94
- 'lt': (forms.IntegerField,),
95
- 'lte': (forms.IntegerField,),
96
- 'range': (searchkit_fields.IntegerRangeField,),
88
+ 'exact': lambda f: forms.IntegerField(),
89
+ 'gt': lambda f: forms.IntegerField(),
90
+ 'gte': lambda f: forms.IntegerField(),
91
+ 'lt': lambda f: forms.IntegerField(),
92
+ 'lte': lambda f: forms.IntegerField(),
93
+ 'range': lambda f: searchkit_fields.IntegerRangeField(),
97
94
  }
98
95
  ),
99
96
  (
100
97
  lambda f: isinstance(f, models.FloatField),
101
98
  {
102
- 'exact': (forms.FloatField,),
103
- 'gt': (forms.FloatField,),
104
- 'gte': (forms.FloatField,),
105
- 'lt': (forms.FloatField,),
106
- 'lte': (forms.FloatField,),
107
- 'range': (searchkit_fields.IntegerRangeField,),
99
+ 'exact': lambda f: forms.FloatField(),
100
+ 'gt': lambda f: forms.FloatField(),
101
+ 'gte': lambda f: forms.FloatField(),
102
+ 'lt': lambda f: forms.FloatField(),
103
+ 'lte': lambda f: forms.FloatField(),
104
+ 'range': lambda f: searchkit_fields.IntegerRangeField(),
108
105
  }
109
106
  ),
110
107
  (
111
108
  lambda f: isinstance(f, models.DecimalField),
112
109
  {
113
- 'exact': (forms.DecimalField,),
114
- 'gt': (forms.DecimalField,),
115
- 'gte': (forms.DecimalField,),
116
- 'lt': (forms.DecimalField,),
117
- 'lte': (forms.DecimalField,),
118
- 'range': (searchkit_fields.IntegerRangeField,),
110
+ 'exact': lambda f: forms.DecimalField(),
111
+ 'gt': lambda f: forms.DecimalField(),
112
+ 'gte': lambda f: forms.DecimalField(),
113
+ 'lt': lambda f: forms.DecimalField(),
114
+ 'lte': lambda f: forms.DecimalField(),
115
+ 'range': lambda f: searchkit_fields.IntegerRangeField(),
119
116
  }
120
117
  ),
121
118
  (
122
119
  lambda f: isinstance(f, models.DateTimeField),
123
120
  {
124
- 'exact': (forms.DateTimeField,),
125
- 'gt': (forms.DateTimeField,),
126
- 'gte': (forms.DateTimeField,),
127
- 'lt': (forms.DateTimeField,),
128
- 'lte': (forms.DateTimeField,),
129
- 'range': (searchkit_fields.DateTimeRangeField,),
121
+ 'exact': lambda f: forms.SplitDateTimeField(widget=AdminSplitDateTime()),
122
+ 'gt': lambda f: forms.SplitDateTimeField(widget=AdminSplitDateTime()),
123
+ 'gte': lambda f: forms.SplitDateTimeField(widget=AdminSplitDateTime()),
124
+ 'lt': lambda f: forms.SplitDateTimeField(widget=AdminSplitDateTime()),
125
+ 'lte': lambda f: forms.SplitDateTimeField(widget=AdminSplitDateTime()),
126
+ 'range': lambda f: searchkit_fields.DateTimeRangeField(),
130
127
  }
131
128
  ),
132
129
  (
133
130
  lambda f: isinstance(f, models.DateField),
134
131
  {
135
- 'exact': (forms.DateField,),
136
- 'gt': (forms.DateField,),
137
- 'gte': (forms.DateField,),
138
- 'lt': (forms.DateField,),
139
- 'lte': (forms.DateField,),
140
- 'range': (searchkit_fields.DateRangeField,),
132
+ 'exact': lambda f: forms.DateField(widget=AdminDateWidget()),
133
+ 'gt': lambda f: forms.DateField(widget=AdminDateWidget()),
134
+ 'gte': lambda f: forms.DateField(widget=AdminDateWidget()),
135
+ 'lt': lambda f: forms.DateField(widget=AdminDateWidget()),
136
+ 'lte': lambda f: forms.DateField(widget=AdminDateWidget()),
137
+ 'range': lambda f: searchkit_fields.DateRangeField(),
141
138
  }
142
139
  ),
143
140
  ))
@@ -155,24 +152,3 @@ class MediaMixin:
155
152
  'admin/js/jquery.init.js',
156
153
  "searchkit/searchkit.js"
157
154
  ]
158
-
159
-
160
- def is_searchable_model(model):
161
- """
162
- Check if the model is searchable by Searchkit.
163
- """
164
- return admin.site.is_registered(model) and SearchkitFilter in admin.site._registry[model].list_filter
165
-
166
-
167
- def get_searchable_models():
168
- """
169
- Return a queryset of searchable models.
170
- """
171
- # Before mirating the database we get an OperationalError when trying to
172
- # access ContentType database table.
173
- try:
174
- models = [m for m in apps.get_models() if is_searchable_model(m)]
175
- ids = [ContentType.objects.get_for_model(m).id for m in models]
176
- return ContentType.objects.filter(pk__in=ids).order_by('app_label', 'model')
177
- except OperationalError:
178
- return ContentType.objects.all()
@@ -19,9 +19,3 @@ class Search(models.Model):
19
19
  for data in self.data:
20
20
  lookups[f'{data["field"]}__{data["operator"]}'] = data['value']
21
21
  return lookups
22
-
23
- def as_queryset(self):
24
- """
25
- Returns a filtered queryset for the model.
26
- """
27
- return self.contenttype.model_class().objects.filter(**self.as_lookups())
@@ -49,7 +49,7 @@ INITIAL_DATA = [
49
49
  dict(
50
50
  field='datetime',
51
51
  operator='exact',
52
- value='2025-05-14 08:45',
52
+ value=['2025-05-14', '08:45'],
53
53
  )
54
54
  ]
55
55
 
@@ -263,8 +263,6 @@ class SearchkitSearchFormTestCase(TestCase):
263
263
  self.assertEqual(len(filter_rules), len(INITIAL_DATA))
264
264
  for data in INITIAL_DATA:
265
265
  self.assertIn(f"{data['field']}__{data['operator']}", filter_rules)
266
- queryset = form.instance.as_queryset()
267
- self.assertTrue(queryset.model == ModelA)
268
266
 
269
267
 
270
268
  class SearchkitModelFormTestCase(TestCase):
@@ -0,0 +1,13 @@
1
+ from django.contrib import admin
2
+
3
+
4
+ def is_searchable_model(model):
5
+ """
6
+ Check if the model is searchable by Searchkit.
7
+ """
8
+ # We do not import SearchkitFilter to avoid circular imports. So we check
9
+ # the filter by its name.
10
+ return (
11
+ admin.site.is_registered(model)
12
+ and 'SearchkitFilter' in [getattr(f, '__name__', '') for f in admin.site._registry[model].list_filter]
13
+ )
@@ -14,9 +14,9 @@ class SearchkitAjaxView(View):
14
14
  Reload the formset via ajax.
15
15
  """
16
16
  def get(self, request, **kwargs):
17
- contenttype_form = SearchkitModelForm(data=self.request.GET)
18
- if contenttype_form.is_valid():
19
- model = contenttype_form.cleaned_data['searchkit_model'].model_class()
17
+ model_form = SearchkitModelForm(data=self.request.GET)
18
+ if model_form.is_valid():
19
+ model = model_form.cleaned_data['searchkit_model'].model_class()
20
20
  formset = searchkit_formset_factory(model=model)(data=request.GET)
21
21
  return HttpResponse(formset.render())
22
22
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-searchkit
3
- Version: 1.1
3
+ Version: 1.3
4
4
  Summary: Finally a real searchkit for django!
5
5
  Home-page: https://github.com/thomst/django-searchkit
6
6
  Author: Thomas Leichtfuß
@@ -0,0 +1,166 @@
1
+ build/lib/build/lib/build/lib/build/lib/example/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ build/lib/build/lib/build/lib/build/lib/example/example/admin.py,sha256=eTZ5mCA1ToGouqYgIf-6xDl2nvYAz7T9lU1Bnu_gP9c,462
3
+ build/lib/build/lib/build/lib/build/lib/example/example/asgi.py,sha256=mqLnzcCH9X-8UhDo5ZhcM8tF3jtALEGSjsBmphbkLcs,391
4
+ build/lib/build/lib/build/lib/build/lib/example/example/models.py,sha256=fB9X782cX01Yg2uIiPCVgrS8C7DkgG9U-9mxGtX3P7Q,1097
5
+ build/lib/build/lib/build/lib/build/lib/example/example/settings.py,sha256=du9bWbAceSvDkYeNYOc_3KxKL1p1se93TdAueT2RQ_E,3256
6
+ build/lib/build/lib/build/lib/build/lib/example/example/urls.py,sha256=D8LxjiTdJSA87AVh3BzpVo5E2aC30hlp20HshPDrfvU,800
7
+ build/lib/build/lib/build/lib/build/lib/example/example/wsgi.py,sha256=OAXHHeNQoj7FBDc5NMET39i_kIGpFrcdNDdY1thrh58,391
8
+ build/lib/build/lib/build/lib/build/lib/example/example/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ build/lib/build/lib/build/lib/build/lib/example/example/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ build/lib/build/lib/build/lib/build/lib/example/example/management/commands/createtestdata.py,sha256=IVtyUqak133h9Ua-Ag_GP8mw3dUdiDYAa2tGmLkKluU,2737
11
+ build/lib/build/lib/build/lib/build/lib/example/example/migrations/0001_initial.py,sha256=62tOi17oHGuqqLmSAYWLep6AMkxCJF6Tp13odghS7gI,2014
12
+ build/lib/build/lib/build/lib/build/lib/example/example/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ build/lib/build/lib/build/lib/build/lib/searchkit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ build/lib/build/lib/build/lib/build/lib/searchkit/__version__.py,sha256=gR3PFKf352QJTKmvgE6eB0I5fdfM4mnk6oQ0ogK2fQs,661
15
+ build/lib/build/lib/build/lib/build/lib/searchkit/admin.py,sha256=0q31L44qoUiB-ZK1JuL3JPWJx7EGbF0DP3GXq0h3Qqc,1671
16
+ build/lib/build/lib/build/lib/build/lib/searchkit/apps.py,sha256=17m6wPu5N59Dq4MLoWaQd0aNHEzMT4z4emQD632GIMA,150
17
+ build/lib/build/lib/build/lib/build/lib/searchkit/filters.py,sha256=lkiJaCxEFGDYYgK1sRg4BMtShBdCIJ5LsatikLJ9Fds,1456
18
+ build/lib/build/lib/build/lib/build/lib/searchkit/models.py,sha256=0LEe0z3jOTqAGrqNGknDDY1L1anaG3kCcQ_Zm_7dl9I,800
19
+ build/lib/build/lib/build/lib/build/lib/searchkit/tests.py,sha256=gzl8T_kENyLY4IHFH75SoIynre-8ml7XMCOFkhIJ23s,14854
20
+ build/lib/build/lib/build/lib/build/lib/searchkit/urls.py,sha256=Mhrq4CUOhrh28ZhRocSP2AYnfWFW2c_eJyMR81q5fps,162
21
+ build/lib/build/lib/build/lib/build/lib/searchkit/utils.py,sha256=UYhddwdLz1sOj-svDk_yTQnIofCdwUvjKVoKBKDtieo,411
22
+ build/lib/build/lib/build/lib/build/lib/searchkit/views.py,sha256=ECSwsge2pD0OJLHdHwpOdWS7XiItUX2NFCO8FSjBigE,919
23
+ build/lib/build/lib/build/lib/build/lib/searchkit/forms/__init__.py,sha256=FBggDa1owkYrceIU3cqNhqsMB49RJWZRAkA4OfvUMcM,207
24
+ build/lib/build/lib/build/lib/build/lib/searchkit/forms/fields.py,sha256=gXQTlB1Gt0mMAtOwregIdRHxY_QoRxX_Envbev1ZUkI,1682
25
+ build/lib/build/lib/build/lib/build/lib/searchkit/forms/search.py,sha256=9YsSE4LDdvFXDApa02lJse5ryuX1Bn6O93VooXWzSDY,2271
26
+ build/lib/build/lib/build/lib/build/lib/searchkit/forms/searchkit.py,sha256=T6qf6f16SNtxEX8Ln-cgKLcbsgosUKSiSH1lmwgyMAQ,6754
27
+ build/lib/build/lib/build/lib/build/lib/searchkit/forms/utils.py,sha256=u5Z9QjuqadGybFF-vGs1yHCEQ5D9j_gRnFSoQH-D8DI,5232
28
+ build/lib/build/lib/build/lib/build/lib/searchkit/migrations/0001_initial.py,sha256=cP886X1UMrDTf-KxfHfuoQ4b1T1lhdNJyVNOGMNyWNw,1093
29
+ build/lib/build/lib/build/lib/build/lib/searchkit/migrations/0002_rename_searchkitsearch_search.py,sha256=RHXShizf689AdPb2Ca-hONWmwZbB2Fs5DQhXlEPE-f0,389
30
+ build/lib/build/lib/build/lib/build/lib/searchkit/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ build/lib/build/lib/build/lib/build/lib/searchkit/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
+ build/lib/build/lib/build/lib/build/lib/searchkit/templatetags/searchkit.py,sha256=HpEGTGYi_enDh_bgTgWdVbZftNuZqRt4J9N5A0Nc1AM,581
33
+ build/lib/build/lib/build/lib/example/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ build/lib/build/lib/build/lib/example/example/admin.py,sha256=eTZ5mCA1ToGouqYgIf-6xDl2nvYAz7T9lU1Bnu_gP9c,462
35
+ build/lib/build/lib/build/lib/example/example/asgi.py,sha256=mqLnzcCH9X-8UhDo5ZhcM8tF3jtALEGSjsBmphbkLcs,391
36
+ build/lib/build/lib/build/lib/example/example/models.py,sha256=fB9X782cX01Yg2uIiPCVgrS8C7DkgG9U-9mxGtX3P7Q,1097
37
+ build/lib/build/lib/build/lib/example/example/settings.py,sha256=du9bWbAceSvDkYeNYOc_3KxKL1p1se93TdAueT2RQ_E,3256
38
+ build/lib/build/lib/build/lib/example/example/urls.py,sha256=D8LxjiTdJSA87AVh3BzpVo5E2aC30hlp20HshPDrfvU,800
39
+ build/lib/build/lib/build/lib/example/example/wsgi.py,sha256=OAXHHeNQoj7FBDc5NMET39i_kIGpFrcdNDdY1thrh58,391
40
+ build/lib/build/lib/build/lib/example/example/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
+ build/lib/build/lib/build/lib/example/example/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
+ build/lib/build/lib/build/lib/example/example/management/commands/createtestdata.py,sha256=IVtyUqak133h9Ua-Ag_GP8mw3dUdiDYAa2tGmLkKluU,2737
43
+ build/lib/build/lib/build/lib/example/example/migrations/0001_initial.py,sha256=62tOi17oHGuqqLmSAYWLep6AMkxCJF6Tp13odghS7gI,2014
44
+ build/lib/build/lib/build/lib/example/example/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
+ build/lib/build/lib/build/lib/searchkit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
+ build/lib/build/lib/build/lib/searchkit/__version__.py,sha256=gR3PFKf352QJTKmvgE6eB0I5fdfM4mnk6oQ0ogK2fQs,661
47
+ build/lib/build/lib/build/lib/searchkit/admin.py,sha256=0q31L44qoUiB-ZK1JuL3JPWJx7EGbF0DP3GXq0h3Qqc,1671
48
+ build/lib/build/lib/build/lib/searchkit/apps.py,sha256=17m6wPu5N59Dq4MLoWaQd0aNHEzMT4z4emQD632GIMA,150
49
+ build/lib/build/lib/build/lib/searchkit/filters.py,sha256=lkiJaCxEFGDYYgK1sRg4BMtShBdCIJ5LsatikLJ9Fds,1456
50
+ build/lib/build/lib/build/lib/searchkit/models.py,sha256=0LEe0z3jOTqAGrqNGknDDY1L1anaG3kCcQ_Zm_7dl9I,800
51
+ build/lib/build/lib/build/lib/searchkit/tests.py,sha256=gzl8T_kENyLY4IHFH75SoIynre-8ml7XMCOFkhIJ23s,14854
52
+ build/lib/build/lib/build/lib/searchkit/urls.py,sha256=Mhrq4CUOhrh28ZhRocSP2AYnfWFW2c_eJyMR81q5fps,162
53
+ build/lib/build/lib/build/lib/searchkit/utils.py,sha256=UYhddwdLz1sOj-svDk_yTQnIofCdwUvjKVoKBKDtieo,411
54
+ build/lib/build/lib/build/lib/searchkit/views.py,sha256=ECSwsge2pD0OJLHdHwpOdWS7XiItUX2NFCO8FSjBigE,919
55
+ build/lib/build/lib/build/lib/searchkit/forms/__init__.py,sha256=FBggDa1owkYrceIU3cqNhqsMB49RJWZRAkA4OfvUMcM,207
56
+ build/lib/build/lib/build/lib/searchkit/forms/fields.py,sha256=gXQTlB1Gt0mMAtOwregIdRHxY_QoRxX_Envbev1ZUkI,1682
57
+ build/lib/build/lib/build/lib/searchkit/forms/search.py,sha256=9YsSE4LDdvFXDApa02lJse5ryuX1Bn6O93VooXWzSDY,2271
58
+ build/lib/build/lib/build/lib/searchkit/forms/searchkit.py,sha256=T6qf6f16SNtxEX8Ln-cgKLcbsgosUKSiSH1lmwgyMAQ,6754
59
+ build/lib/build/lib/build/lib/searchkit/forms/utils.py,sha256=u5Z9QjuqadGybFF-vGs1yHCEQ5D9j_gRnFSoQH-D8DI,5232
60
+ build/lib/build/lib/build/lib/searchkit/migrations/0001_initial.py,sha256=cP886X1UMrDTf-KxfHfuoQ4b1T1lhdNJyVNOGMNyWNw,1093
61
+ build/lib/build/lib/build/lib/searchkit/migrations/0002_rename_searchkitsearch_search.py,sha256=RHXShizf689AdPb2Ca-hONWmwZbB2Fs5DQhXlEPE-f0,389
62
+ build/lib/build/lib/build/lib/searchkit/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
+ build/lib/build/lib/build/lib/searchkit/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
+ build/lib/build/lib/build/lib/searchkit/templatetags/searchkit.py,sha256=HpEGTGYi_enDh_bgTgWdVbZftNuZqRt4J9N5A0Nc1AM,581
65
+ build/lib/build/lib/example/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
+ build/lib/build/lib/example/example/admin.py,sha256=KDjYyHPEqNdv7Xe8yx0VuWdx-bDn7qKKHM5ZYhFwdU0,445
67
+ build/lib/build/lib/example/example/asgi.py,sha256=mqLnzcCH9X-8UhDo5ZhcM8tF3jtALEGSjsBmphbkLcs,391
68
+ build/lib/build/lib/example/example/models.py,sha256=fB9X782cX01Yg2uIiPCVgrS8C7DkgG9U-9mxGtX3P7Q,1097
69
+ build/lib/build/lib/example/example/settings.py,sha256=du9bWbAceSvDkYeNYOc_3KxKL1p1se93TdAueT2RQ_E,3256
70
+ build/lib/build/lib/example/example/urls.py,sha256=D8LxjiTdJSA87AVh3BzpVo5E2aC30hlp20HshPDrfvU,800
71
+ build/lib/build/lib/example/example/wsgi.py,sha256=OAXHHeNQoj7FBDc5NMET39i_kIGpFrcdNDdY1thrh58,391
72
+ build/lib/build/lib/example/example/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
+ build/lib/build/lib/example/example/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
+ build/lib/build/lib/example/example/management/commands/createtestdata.py,sha256=IVtyUqak133h9Ua-Ag_GP8mw3dUdiDYAa2tGmLkKluU,2737
75
+ build/lib/build/lib/example/example/migrations/0001_initial.py,sha256=62tOi17oHGuqqLmSAYWLep6AMkxCJF6Tp13odghS7gI,2014
76
+ build/lib/build/lib/example/example/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
+ build/lib/build/lib/searchkit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
+ build/lib/build/lib/searchkit/__version__.py,sha256=gR3PFKf352QJTKmvgE6eB0I5fdfM4mnk6oQ0ogK2fQs,661
79
+ build/lib/build/lib/searchkit/admin.py,sha256=0q31L44qoUiB-ZK1JuL3JPWJx7EGbF0DP3GXq0h3Qqc,1671
80
+ build/lib/build/lib/searchkit/apps.py,sha256=17m6wPu5N59Dq4MLoWaQd0aNHEzMT4z4emQD632GIMA,150
81
+ build/lib/build/lib/searchkit/filters.py,sha256=lkiJaCxEFGDYYgK1sRg4BMtShBdCIJ5LsatikLJ9Fds,1456
82
+ build/lib/build/lib/searchkit/models.py,sha256=0LEe0z3jOTqAGrqNGknDDY1L1anaG3kCcQ_Zm_7dl9I,800
83
+ build/lib/build/lib/searchkit/tests.py,sha256=gzl8T_kENyLY4IHFH75SoIynre-8ml7XMCOFkhIJ23s,14854
84
+ build/lib/build/lib/searchkit/urls.py,sha256=Mhrq4CUOhrh28ZhRocSP2AYnfWFW2c_eJyMR81q5fps,162
85
+ build/lib/build/lib/searchkit/utils.py,sha256=UYhddwdLz1sOj-svDk_yTQnIofCdwUvjKVoKBKDtieo,411
86
+ build/lib/build/lib/searchkit/views.py,sha256=ECSwsge2pD0OJLHdHwpOdWS7XiItUX2NFCO8FSjBigE,919
87
+ build/lib/build/lib/searchkit/forms/__init__.py,sha256=FBggDa1owkYrceIU3cqNhqsMB49RJWZRAkA4OfvUMcM,207
88
+ build/lib/build/lib/searchkit/forms/fields.py,sha256=gXQTlB1Gt0mMAtOwregIdRHxY_QoRxX_Envbev1ZUkI,1682
89
+ build/lib/build/lib/searchkit/forms/search.py,sha256=9YsSE4LDdvFXDApa02lJse5ryuX1Bn6O93VooXWzSDY,2271
90
+ build/lib/build/lib/searchkit/forms/searchkit.py,sha256=T6qf6f16SNtxEX8Ln-cgKLcbsgosUKSiSH1lmwgyMAQ,6754
91
+ build/lib/build/lib/searchkit/forms/utils.py,sha256=u5Z9QjuqadGybFF-vGs1yHCEQ5D9j_gRnFSoQH-D8DI,5232
92
+ build/lib/build/lib/searchkit/migrations/0001_initial.py,sha256=cP886X1UMrDTf-KxfHfuoQ4b1T1lhdNJyVNOGMNyWNw,1093
93
+ build/lib/build/lib/searchkit/migrations/0002_rename_searchkitsearch_search.py,sha256=RHXShizf689AdPb2Ca-hONWmwZbB2Fs5DQhXlEPE-f0,389
94
+ build/lib/build/lib/searchkit/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
95
+ build/lib/build/lib/searchkit/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
96
+ build/lib/build/lib/searchkit/templatetags/searchkit.py,sha256=HpEGTGYi_enDh_bgTgWdVbZftNuZqRt4J9N5A0Nc1AM,581
97
+ build/lib/example/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
98
+ build/lib/example/example/admin.py,sha256=KDjYyHPEqNdv7Xe8yx0VuWdx-bDn7qKKHM5ZYhFwdU0,445
99
+ build/lib/example/example/asgi.py,sha256=mqLnzcCH9X-8UhDo5ZhcM8tF3jtALEGSjsBmphbkLcs,391
100
+ build/lib/example/example/models.py,sha256=fB9X782cX01Yg2uIiPCVgrS8C7DkgG9U-9mxGtX3P7Q,1097
101
+ build/lib/example/example/settings.py,sha256=du9bWbAceSvDkYeNYOc_3KxKL1p1se93TdAueT2RQ_E,3256
102
+ build/lib/example/example/urls.py,sha256=D8LxjiTdJSA87AVh3BzpVo5E2aC30hlp20HshPDrfvU,800
103
+ build/lib/example/example/wsgi.py,sha256=OAXHHeNQoj7FBDc5NMET39i_kIGpFrcdNDdY1thrh58,391
104
+ build/lib/example/example/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
105
+ build/lib/example/example/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
+ build/lib/example/example/management/commands/createtestdata.py,sha256=IVtyUqak133h9Ua-Ag_GP8mw3dUdiDYAa2tGmLkKluU,2737
107
+ build/lib/example/example/migrations/0001_initial.py,sha256=62tOi17oHGuqqLmSAYWLep6AMkxCJF6Tp13odghS7gI,2014
108
+ build/lib/example/example/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
+ build/lib/searchkit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
110
+ build/lib/searchkit/__version__.py,sha256=gR3PFKf352QJTKmvgE6eB0I5fdfM4mnk6oQ0ogK2fQs,661
111
+ build/lib/searchkit/admin.py,sha256=0q31L44qoUiB-ZK1JuL3JPWJx7EGbF0DP3GXq0h3Qqc,1671
112
+ build/lib/searchkit/apps.py,sha256=17m6wPu5N59Dq4MLoWaQd0aNHEzMT4z4emQD632GIMA,150
113
+ build/lib/searchkit/filters.py,sha256=lkiJaCxEFGDYYgK1sRg4BMtShBdCIJ5LsatikLJ9Fds,1456
114
+ build/lib/searchkit/models.py,sha256=0LEe0z3jOTqAGrqNGknDDY1L1anaG3kCcQ_Zm_7dl9I,800
115
+ build/lib/searchkit/tests.py,sha256=gzl8T_kENyLY4IHFH75SoIynre-8ml7XMCOFkhIJ23s,14854
116
+ build/lib/searchkit/urls.py,sha256=Mhrq4CUOhrh28ZhRocSP2AYnfWFW2c_eJyMR81q5fps,162
117
+ build/lib/searchkit/utils.py,sha256=UYhddwdLz1sOj-svDk_yTQnIofCdwUvjKVoKBKDtieo,411
118
+ build/lib/searchkit/views.py,sha256=ECSwsge2pD0OJLHdHwpOdWS7XiItUX2NFCO8FSjBigE,919
119
+ build/lib/searchkit/forms/__init__.py,sha256=FBggDa1owkYrceIU3cqNhqsMB49RJWZRAkA4OfvUMcM,207
120
+ build/lib/searchkit/forms/fields.py,sha256=gXQTlB1Gt0mMAtOwregIdRHxY_QoRxX_Envbev1ZUkI,1682
121
+ build/lib/searchkit/forms/search.py,sha256=9YsSE4LDdvFXDApa02lJse5ryuX1Bn6O93VooXWzSDY,2271
122
+ build/lib/searchkit/forms/searchkit.py,sha256=T6qf6f16SNtxEX8Ln-cgKLcbsgosUKSiSH1lmwgyMAQ,6754
123
+ build/lib/searchkit/forms/utils.py,sha256=u5Z9QjuqadGybFF-vGs1yHCEQ5D9j_gRnFSoQH-D8DI,5232
124
+ build/lib/searchkit/migrations/0001_initial.py,sha256=cP886X1UMrDTf-KxfHfuoQ4b1T1lhdNJyVNOGMNyWNw,1093
125
+ build/lib/searchkit/migrations/0002_rename_searchkitsearch_search.py,sha256=RHXShizf689AdPb2Ca-hONWmwZbB2Fs5DQhXlEPE-f0,389
126
+ build/lib/searchkit/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
127
+ build/lib/searchkit/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
128
+ build/lib/searchkit/templatetags/searchkit.py,sha256=HpEGTGYi_enDh_bgTgWdVbZftNuZqRt4J9N5A0Nc1AM,581
129
+ django_searchkit-1.3.dist-info/licenses/LICENCE,sha256=oqmlRYPA5GHG2T1yp8fPFGQdOO-NnJPdGITeFiJYWLg,1521
130
+ example/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
131
+ example/example/admin.py,sha256=KDjYyHPEqNdv7Xe8yx0VuWdx-bDn7qKKHM5ZYhFwdU0,445
132
+ example/example/asgi.py,sha256=mqLnzcCH9X-8UhDo5ZhcM8tF3jtALEGSjsBmphbkLcs,391
133
+ example/example/models.py,sha256=fB9X782cX01Yg2uIiPCVgrS8C7DkgG9U-9mxGtX3P7Q,1097
134
+ example/example/settings.py,sha256=du9bWbAceSvDkYeNYOc_3KxKL1p1se93TdAueT2RQ_E,3256
135
+ example/example/urls.py,sha256=D8LxjiTdJSA87AVh3BzpVo5E2aC30hlp20HshPDrfvU,800
136
+ example/example/wsgi.py,sha256=OAXHHeNQoj7FBDc5NMET39i_kIGpFrcdNDdY1thrh58,391
137
+ example/example/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
138
+ example/example/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
139
+ example/example/management/commands/createtestdata.py,sha256=IVtyUqak133h9Ua-Ag_GP8mw3dUdiDYAa2tGmLkKluU,2737
140
+ example/example/migrations/0001_initial.py,sha256=62tOi17oHGuqqLmSAYWLep6AMkxCJF6Tp13odghS7gI,2014
141
+ example/example/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
142
+ searchkit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
143
+ searchkit/__version__.py,sha256=gR3PFKf352QJTKmvgE6eB0I5fdfM4mnk6oQ0ogK2fQs,661
144
+ searchkit/admin.py,sha256=0q31L44qoUiB-ZK1JuL3JPWJx7EGbF0DP3GXq0h3Qqc,1671
145
+ searchkit/apps.py,sha256=17m6wPu5N59Dq4MLoWaQd0aNHEzMT4z4emQD632GIMA,150
146
+ searchkit/filters.py,sha256=lkiJaCxEFGDYYgK1sRg4BMtShBdCIJ5LsatikLJ9Fds,1456
147
+ searchkit/models.py,sha256=0LEe0z3jOTqAGrqNGknDDY1L1anaG3kCcQ_Zm_7dl9I,800
148
+ searchkit/tests.py,sha256=gzl8T_kENyLY4IHFH75SoIynre-8ml7XMCOFkhIJ23s,14854
149
+ searchkit/urls.py,sha256=Mhrq4CUOhrh28ZhRocSP2AYnfWFW2c_eJyMR81q5fps,162
150
+ searchkit/utils.py,sha256=UYhddwdLz1sOj-svDk_yTQnIofCdwUvjKVoKBKDtieo,411
151
+ searchkit/views.py,sha256=ECSwsge2pD0OJLHdHwpOdWS7XiItUX2NFCO8FSjBigE,919
152
+ searchkit/forms/__init__.py,sha256=FBggDa1owkYrceIU3cqNhqsMB49RJWZRAkA4OfvUMcM,207
153
+ searchkit/forms/fields.py,sha256=gXQTlB1Gt0mMAtOwregIdRHxY_QoRxX_Envbev1ZUkI,1682
154
+ searchkit/forms/search.py,sha256=9YsSE4LDdvFXDApa02lJse5ryuX1Bn6O93VooXWzSDY,2271
155
+ searchkit/forms/searchkit.py,sha256=T6qf6f16SNtxEX8Ln-cgKLcbsgosUKSiSH1lmwgyMAQ,6754
156
+ searchkit/forms/utils.py,sha256=u5Z9QjuqadGybFF-vGs1yHCEQ5D9j_gRnFSoQH-D8DI,5232
157
+ searchkit/migrations/0001_initial.py,sha256=cP886X1UMrDTf-KxfHfuoQ4b1T1lhdNJyVNOGMNyWNw,1093
158
+ searchkit/migrations/0002_rename_searchkitsearch_search.py,sha256=RHXShizf689AdPb2Ca-hONWmwZbB2Fs5DQhXlEPE-f0,389
159
+ searchkit/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
160
+ searchkit/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
161
+ searchkit/templatetags/searchkit.py,sha256=HpEGTGYi_enDh_bgTgWdVbZftNuZqRt4J9N5A0Nc1AM,581
162
+ django_searchkit-1.3.dist-info/METADATA,sha256=yi3p_QFsJU_UlkQ5uvqdegoVDDTl5sPd5x0mHHMaazE,3325
163
+ django_searchkit-1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
164
+ django_searchkit-1.3.dist-info/top_level.txt,sha256=-4gF42VIaG-ckn2rb2wFa7LhxIZymHBsYVedNOr_NIY,29
165
+ django_searchkit-1.3.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
166
+ django_searchkit-1.3.dist-info/RECORD,,
searchkit/__version__.py CHANGED
@@ -13,4 +13,4 @@ Version 0.x should be considered a development version with an unstable API,
13
13
  and backwards compatibility is not guaranteed for minor versions.
14
14
  """
15
15
 
16
- __version__ = "1.1"
16
+ __version__ = "1.3"
searchkit/admin.py CHANGED
@@ -1,15 +1,18 @@
1
1
  from django.contrib import admin
2
2
  from django.http import HttpResponseRedirect
3
3
  from django.urls import reverse
4
+ from django.utils.html import format_html
4
5
  from .models import Search
5
6
  from .forms import SearchForm
6
7
  from .filters import SearchkitFilter
8
+ from .filters import SearchableModelFilter
7
9
 
8
10
 
9
11
  @admin.register(Search)
10
12
  class SearchkitSearchAdmin(admin.ModelAdmin):
11
13
  form = SearchForm
12
- list_display = ('name', 'contenttype', 'created_date')
14
+ list_display = ('name', 'contenttype', 'created_date', 'apply_search_view')
15
+ list_filter = (('contenttype', SearchableModelFilter),)
13
16
 
14
17
  def get_url_for_applied_search(self, obj):
15
18
  app_label = obj.contenttype.app_label
@@ -28,3 +31,14 @@ class SearchkitSearchAdmin(admin.ModelAdmin):
28
31
  return HttpResponseRedirect(self.get_url_for_applied_search(obj))
29
32
  else:
30
33
  return super().response_change(request, obj, *args, **kwargs)
34
+
35
+ def apply_search_view(self, obj):
36
+ """
37
+ Returns a link to apply the search.
38
+ """
39
+ return format_html(
40
+ '<a href="{}" >Apply search "{}"</a>',
41
+ self.get_url_for_applied_search(obj),
42
+ obj.name
43
+ )
44
+ apply_search_view.short_description = 'Apply Search'
searchkit/filters.py CHANGED
@@ -1,9 +1,10 @@
1
- from django.contrib.admin import SimpleListFilter
1
+ from django.contrib import admin
2
2
  from django.contrib.contenttypes.models import ContentType
3
3
  from .models import Search
4
+ from .utils import is_searchable_model
4
5
 
5
6
 
6
- class SearchkitFilter(SimpleListFilter):
7
+ class SearchkitFilter(admin.SimpleListFilter):
7
8
  title = 'Searchkit Filter'
8
9
  parameter_name = 'search'
9
10
  template = 'searchkit/searchkit_filter.html'
@@ -14,14 +15,22 @@ class SearchkitFilter(SimpleListFilter):
14
15
  self.searchkit_model = ContentType.objects.get_for_model(model)
15
16
  super().__init__(request, params, model, model_admin)
16
17
 
18
+ def has_output(self):
19
+ return True
20
+
17
21
  def lookups(self, request, model_admin):
18
- # Fetch the last three objects from SearchkitSearch and return them as
19
- # choices.
20
- searches = Search.objects.filter(contenttype=self.searchkit_model).order_by('-created_date')[:3]
22
+ searches = Search.objects.filter(contenttype=self.searchkit_model).order_by('-created_date')
21
23
  return [(str(obj.id), obj.name) for obj in searches]
22
24
 
23
25
  def queryset(self, request, queryset):
24
26
  # Filter the queryset based on the selected SearchkitSearch object
25
27
  if self.value():
26
28
  search = Search.objects.get(id=int(self.value()))
27
- return search.as_queryset()
29
+ return queryset.filter(**search.as_lookups())
30
+
31
+
32
+ class SearchableModelFilter(admin.filters.RelatedFieldListFilter):
33
+ def __init__(self, *args, **kwargs):
34
+ super().__init__(*args, **kwargs)
35
+ contenttypes = ContentType.objects.order_by('app_label', 'model')
36
+ self.lookup_choices = [(m.id, m) for m in contenttypes if is_searchable_model(m.model_class())]
searchkit/forms/fields.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from django import forms
2
+ from django.contrib.admin import widgets
2
3
  from django.utils.translation import gettext_lazy as _
3
4
 
4
5
 
@@ -46,10 +47,10 @@ class IntegerRangeField(BaseRangeField):
46
47
  class DateRangeField(BaseRangeField):
47
48
  incomplete_message = _("Enter the first and the last date.")
48
49
  field_type = forms.DateField
49
- widget_type = forms.DateInput
50
+ widget_type = widgets.AdminDateWidget
50
51
 
51
52
 
52
- class DateTimeRangeField(BaseRangeField):
53
+ class DateTimeRangeField(DateRangeField):
53
54
  incomplete_message = _("Enter the first and the last datetime.")
54
- field_type = forms.DateTimeField
55
- widget_type = forms.DateTimeInput
55
+ field_type = forms.SplitDateTimeField
56
+ widget_type = widgets.AdminSplitDateTime
searchkit/forms/search.py CHANGED
@@ -1,6 +1,5 @@
1
1
  from django import forms
2
2
  from django.utils.functional import cached_property
3
- from django.contrib.contenttypes.models import ContentType
4
3
  from ..models import Search
5
4
  from .searchkit import SearchkitModelForm
6
5
  from .searchkit import searchkit_formset_factory