最新消息:20210917 已从crifan.com换到crifan.org

【已解决】Django中用Q的filter出错:django.core.exceptions.FieldError: Related Field got invalid lookup: icontains

Django crifan 2755浏览 0评论

折腾:

【已解决】给内容管理系统中添加按Topic去筛选

期间,搞懂了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

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
99 queries in 0.182 seconds, using 23.40MB memory