models.py
# models.py
#
from django.db import models
from haystack.utils.geo import Point
class Location(models.Model):
latitude = models.FloatField()
longitude = models.FloatField()
address = models.CharField(max_length=100)
city = models.CharField(max_length=30)
zip_code = models.CharField(max_length=10)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.address
@property
def coordinates(self):
return Point(self.longitude, self.latitude)
search_indexes.py
文件必须以search_indexes.py命名
#
# search_indexes.py
#
from django.utils import timezone
from haystack import indexes
from .models import Location
class LocationIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
address = indexes.CharField(model_attr="address")
city = indexes.CharField(model_attr="city")
zip_code = indexes.CharField(model_attr="zip_code")
autocomplete = indexes.EdgeNgramField()
coordinates = indexes.LocationField(model_attr="coordinates")
@staticmethod
def prepare_autocomplete(obj):
return " ".join((
obj.address, obj.city, obj.zip_code
))
def get_model(self):
return Location
def index_queryset(self, using=None):
return self.get_model().objects.filter(
created__lte=timezone.now()
)
views.py
对于通用的Django REST Framework视图,您可以执行以下操作
# views.py
#
from drf_haystack.serializers import HaystackSerializer
from drf_haystack.viewsets import HaystackViewSet
from .models import Location
from .search_indexes import LocationIndex
class LocationSerializer(HaystackSerializer):
class Meta:
# The `index_classes` attribute is a list of which search indexes
# we want to include in the search.
index_classes = [LocationIndex]
# The `fields` contains all the fields we want to include.
# NOTE: Make sure you don't confuse these with model attributes. These
# fields belong to the search index!
fields = [
"text", "address", "city", "zip_code", "autocomplete"
]
class LocationSearchView(HaystackViewSet):
# `index_models` is an optional list of which models you would like to include
# in the search result. You might have several models indexed, and this provides
# a way to filter out those of no interest for this particular view.
# (Translates to `SearchQuerySet().models(*index_models)` behind the scenes.
index_models = [Location]
serializer_class = LocationSerializer
urls.py
将视图连接到urls.py文件中。
在路由器中连接视图时,请确保指定了base_name属性。由于我们没有用于视图的任何单一模型,因此路由器无法自动计算出视图的基本名称。
# urls.py
#
from django.conf.urls import patterns, url, include
from rest_framework import routers
from .views import LocationSearchView
router = routers.DefaultRouter()
router.register("location/search", LocationSearchView, base_name="location-search")
urlpatterns = patterns(
"",
url(r"/api/v1/", include(router.urls)),
)
使用python manage.py rebuild_index重建索引文件