折腾:
期间,搞懂了xxx__icontains的意思后,然后照葫芦画瓢写成:
if topic:
filter_condition = filter_condition | Q(topic__icontains=topic)
if second_level_topic:
filter_condition = filter_condition | Q(second_level_topic__icontains=second_level_topic)
结果报错:
queryset = Script.objects.filter(pk__in=result).filter(filter_condition).order_by(‘-created_at’)
…
File "/usr/local/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1215, in build_filter
condition = self.build_lookup(lookups, col, value)
File "/usr/local/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1076, in build_lookup
raise FieldError(‘Related Field got invalid lookup: {}’.format(lookup_name))
django.core.exceptions.FieldError: Related Field got invalid lookup: icontains
然后自己再去通过:
其定义:
apps/script/models.py
class Script(TimestampedModel):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
place = models.CharField(null=False, blank=False, max_length=128)
title = models.CharField(null=False, blank=False, max_length=128)
topic = models.ForeignKey(‘Topic’, on_delete=models.PROTECT,
default=”,
related_name=’script_topic’)
second_level_topic = models.ForeignKey(‘Topic’, on_delete=models.PROTECT,
null=True, blank=True, default=”,
related_name=’script_topic_second_level’)
class Topic(models.Model):
name = models.CharField(max_length=100)
type = models.CharField(max_length=20)
和:
创建时的传值:
def create(self, request, *args, **kwargs):
topic = request.data.get(‘topic’)
second_level_topic = request.data.get(‘second_level_topic’)
if topic:
topic = Topic.objects.get(name=topic, type=’sectorTopic’)
if second_level_topic:
second_level_topic = Topic.objects.get(name=second_level_topic, type=’topic’)
看出是topic和second_level_topic都是对象,而不是普通字符串,且是外键
所以问题就转化为:如何用Query(QuerySet)去加上字段为对象(而不是普通字符串)的filter
难道是直接再用__去引用对应字段:
topic__name__icontains
?
django Q filter object field
Query-related classes | Django documentation | Django
旧版本1.7的,放弃不看。
django filtering with q objects with dynamic fields – Stack Overflow
django Q filter object not string
python – How do I do a not equal in Django queryset filtering? – Stack Overflow
Making queries | Django documentation | Django
Entry.objects.filter(pub_date__year=2006)
Entry.objects.all().filter(pub_date__year=2006)
好像就是这么直接写的。
去试试
但是突然想到,万一:
filter(yourObject__subField=xxx)
中的yourObject的subField的名字和Django中Q支持的:
https://stackoverflow.com/questions/687295/how-do-i-do-a-not-equal-in-django-queryset-filtering
总结的操作符:
exact
iexact
contains
icontains
in
gt
gte
lt
lte
startswith
istartswith
endswith
iendswith
range
year
month
day
week_day
isnull
search
regex
iregex
有重名的话,那系统岂不是无法识别:
到底是yourObject的subField
还是Django中yourObject的操作符
了?
先不管这么高级的问题了
先去试试此处是否生效再说
然后改为:
if topic:
# filter_condition = filter_condition | Q(topic__icontains=topic)
filter_condition = filter_condition | Q(topic__name__icontains=topic)
if second_level_topic:
# filter_condition = filter_condition | Q(second_level_topic__icontains=second_level_topic)
filter_condition = filter_condition | Q(second_level_topic__name__icontains=second_level_topic)
就可以了:
前端:
后端:
转载请注明:在路上 » 【已解决】Django中用Q的filter出错:django.core.exceptions.FieldError: Related Field got invalid lookup: icontains