gpt4 book ai didi

python - 自定义查找未在 Django 中注册

转载 作者:太空宇宙 更新时间:2023-11-04 03:02:19 25 4
gpt4 key购买 nike

我已经创建了一个自定义查找。我正在使用它进行查询,但是,当我这样做时,错误 Related Field got invalid lookup: lcb被抛出。

我假设这是因为没有正确注册此自定义查找。正如您将在下面看到的,我已经尝试了几件事,但我不知道问题出在哪里。

这是我的代码:

tenants/views.py

from main.lookups import *

def find_tenants(request, house_id):
house = HouseListing.objects.get(pk=house_id)
applications = HousingApplication.objects.filter(date_from__gte=house.available_from)
applications = applications.filter(pets__lcb=house.allowed_pets.values_list('id', flat=True))

context = {'house': house, 'applications': applications}
return render(request, 'landlords/find-tenants.html', context)

ma​​in/lookups.py

from django.db.models import Lookup, ManyToManyField


# Custom lookups

@ManyToManyField.register_lookup
class ListContainedBy(Lookup):
lookup_name = 'lcb'

def as_sql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
return '%s <@ %s' % (lhs, rhs), params

我觉得这很奇怪,因为the docs建议在 AppConfig 中注册查找,或在 models.py .我已经尝试了这两种方法,但都没有用。

回溯

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/landlords/find-tenants/5/

Django Version: 1.10.2
Python Version: 2.7.12
Installed Applications:
['main.apps.MainConfig',
'tenants.apps.TenantsConfig',
'landlords.apps.LandlordsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'django.contrib.postgres',
'imagekit']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner
39. response = get_response(request)

File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/core/handlers/base.py" in _legacy_get_response
249. response = self._get_response(request)

File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)

File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
23. return view_func(request, *args, **kwargs)

File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
23. return view_func(request, *args, **kwargs)

File "/Users/mightyspaj/Development/Projects/housingfinder/housingfinder/landlords/views.py" in find_tenants
132. applications = applications.filter(pets__lcb=house.allowed_pets.values_list('id', flat=True))

File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/db/models/query.py" in filter
796. return self._filter_or_exclude(False, *args, **kwargs)

File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/db/models/query.py" in _filter_or_exclude
814. clone.query.add_q(Q(*args, **kwargs))

File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/db/models/sql/query.py" in add_q
1227. clause, _ = self._add_q(q_object, self.used_aliases)

File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/db/models/sql/query.py" in _add_q
1253. allow_joins=allow_joins, split_subq=split_subq,

File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/db/models/sql/query.py" in build_filter
1178. lookup_class = field.get_lookup(lookups[0])

File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/db/models/fields/related.py" in get_lookup
694. raise TypeError('Related Field got invalid lookup: %s' % lookup_name)

Exception Type: TypeError at /landlords/find-tenants/5/
Exception Value: Related Field got invalid lookup: lcb

到目前为止我尝试过的所有事情

  1. MainConfig.ready() 中注册查找功能
  2. find_tenants() 中注册查找查看
  3. main/models.py 中注册查询
  4. 将查找注册为 Field而不是 ManyToManyField
  5. 使用 ManyToManyField.register_lookup() 注册查找而不是装饰器
  6. 正在更改 %s <@ %s%s = %s .我认为问题可能是它认为我的 SQL 无效

最佳答案

编辑2

看起来有些困惑可能会在 django 的更高版本中得到解决...下面的编辑 1 是针对 1.10 的,但是代码在提示上有所不同,所以也许现在已经修复了。您可以尝试升级到 1.11 并查看是否可以解决问题。但如果这不起作用,我在下面列出的选项仍然值得一试。

编辑 1

我意识到我误解了我最初回答中的异常。实际上,被命中的异常是 django.db.models.fields.related.ForeignObject.get_lookup 中的异常,并且那里的代码更清楚 django 不支持关系字段上的自定义查找:

class ForeignObject(RelatedField):

...

def get_lookup(self, lookup_name):
if lookup_name == 'in':
return RelatedIn
elif lookup_name == 'exact':
return RelatedExact
elif lookup_name == 'gt':
return RelatedGreaterThan
elif lookup_name == 'gte':
return RelatedGreaterThanOrEqual
elif lookup_name == 'lt':
return RelatedLessThan
elif lookup_name == 'lte':
return RelatedLessThanOrEqual
elif lookup_name == 'isnull':
return RelatedIsNull
else:
raise TypeError('Related Field got invalid lookup: %s' % lookup_name)

...

有几件事是您可以尝试让它工作的一件事:

  1. 通过多对多关系在其中一个字段上实现自定义查找,因此您会有如下查询

    applications = applications.filter(
    pets__id__lcb=house.allowed_pets.values_list('id', flat=True))

    我能够使用 IN 运算符按照这些思路进行工作。

  2. 或者,您可以子类化您正在使用的 ForeignObject 并覆盖 get_lookup,这样它就不会为您的新运算符...毫无疑问,您必须做一些小事才能使其正常工作。 编辑: 我试过了,但没有成功工作,因为它比这更复杂,并且对于连接操作,它是来自右侧表的隐式字段,即使用的 Field,因此将 Field 子类化为左侧手头不够用。选项 1 似乎绝对是正确的方法。

原始答案

我相信异常是在告诉您 django 不会尝试对关系字段使用自定义查找。鉴于你提到它,我猜 pets 是一个 ManyToManyField,即一个关系字段,所以我猜你的查找已经注册,django 只是拒绝使用它。

您正在点击的 django 中的代码位(在 django.db.models.sql.query.Query.build_filter() 中)是:

....
if field.is_relation:
# No support for transforms for relational fields
num_lookups = len(lookups)
if num_lookups > 1:
raise FieldError('Related Field got invalid lookup: {}'.format(lookups[0]))
....

我不能说我完全理解其中的原理,但这肯定可以解释为什么无论您尝试使用何种机制来注册查找,您都会得到相同的结果。

这似乎是一个没有很好记录的问题。我在网上唯一能找到的(搜索 10 分钟)是 this ,其他人得出了相同的结论。

关于python - 自定义查找未在 Django 中注册,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40570943/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com