Tôi có hai kiểu: City
và bí danhCityAlias
. Mô hình CityAlias
chứa tất cả các tên trong số City
, cộng với bí danh. Những gì tôi muốn là bất cứ khi nào City
được tìm kiếm theo name
, mô hình CityAlias
sẽ được truy vấn. Đây là những gì tôi đã đưa ra:Tra cứu chuỗi thông qua bộ truy vấn
class CityQuerySet(models.QuerySet):
""" If City is searched by name, search it in CityAlias """
def _search_name_in_alias(self, args, kwargs):
for q in args:
if not isinstance(q, models.Q): continue
for i, child in enumerate(q.children):
# q.children is a list of tuples of queries:
# [('name__iexact', 'calcutta'), ('state__icontains', 'bengal')]
if child[0].startswith('name'):
q.children[i] = ('aliases__%s' % child[0], child[1])
for filter_name in kwargs:
if filter_name.startswith('name'):
kwargs['aliases__%s' % filter_name] = kwargs.pop(filter_name)
def _filter_or_exclude(self, negate, *args, **kwargs):
# handles 'get', 'filter' and 'exclude' methods
self._search_name_in_alias(args=args, kwargs=kwargs)
return super(CityQuerySet, self)._filter_or_exclude(negate, *args, **kwargs)
class City(models.Model):
name = models.CharField(max_length=255, db_index=True)
state = models.ForeignKey(State, related_name='cities')
objects = CityQuerySet.as_manager()
class CityAlias(models.Model):
name = models.CharField(max_length=255, db_index=True)
city = models.ForeignKey(City, related_name='aliases')
Ví dụ: Kolkata
sẽ có một mục trong City
mô hình, và nó sẽ có hai mục trong mô hình CityAlias
: Kolkata
và Calcutta
. Trên QuerySet
cho phép sử dụng tra cứu trên trường name
. Vì vậy, hai truy vấn sau sẽ trả về cùng một mục:
City.objects.get(name='Kolkata') # <City: Kolkata>
City.objects.get(name__iexact='calcutta') # <City: Kolkata>
Cho đến nay rất tốt. Nhưng vấn đề nảy sinh khi City
là một ForeignKey
trong một số mô hình khác:
class Trip(models.Model):
destination = models.ForeignKey(City)
# some other fields....
Trip.objects.filter(destination__name='Kolkata').count() # some non-zero number
Trip.objects.filter(destination__name='Calcutta').count() # always returns zero
Django nội bộ xử lý những tham gia khác nhau, và không gọi phương thức get_queryset
của người quản lý City
's. Cách khác là để gọi các truy vấn trên như sau:
Trip.objects.filter(destination=City.objects.get(name='Calcutta'))
Câu hỏi của tôi là tôi có thể làm điều gì đó, vì vậy mà tuy nhiên mô hình City
được tìm kiếm bởi name
, nó luôn luôn tìm kiếm trong bảng CityAlias
để thay thế? Hoặc có cách nào khác tốt hơn để triển khai chức năng tôi yêu cầu không?
Bạn có quá phức tạp với vấn đề của mình không? Bạn có thể chỉ đơn giản là có Trip.destination là một ngoại ngữ cho thành phố? – dkarchmer
Mô hình 'Thành phố' cũng sẽ có các trường khác (như định vị địa lý) .. do đó, nó có nghĩa là sử dụng 'CityAlias' khi lọc theo tên và' Thành phố' khi các bộ lọc khác được áp dụng. – jatinderjit
Đã thử điều này: Trip.objects.filter (destination__aliases__name = 'Calcutta'). Count() –