Django:`__endswith`的匡威

Ram*_*hum 6 python django django-models

Django允许我这样做:

chair = Chair.objects.filter(name__endswith='hello')
Run Code Online (Sandbox Code Playgroud)

但我想这样做:

chair = Chair.objects.filter(name__isendof='hello')
Run Code Online (Sandbox Code Playgroud)

我知道查找__isendof不存在.但是我想要这样的东西.我希望它与之相反__endswith.它应该找到所有这样的椅子'hello'.endswith(chair.name).

可能在Django?ORM操作比SQL操作更好.

ale*_*cxe 6

Django ORM不是一个银弹,在编写部分SQL时没有任何问题,以防处理简单的ORM很困难或不可能.这是一个非常好的用例extra():

Entry.objects.extra(where=['"hello" LIKE CONCAT("%%", name)'])
Run Code Online (Sandbox Code Playgroud)

请注意,因为我们在这里编写纯SQL - 无论如何它都是数据库后端特定的.这个特定是特定于mysql并且基于这个主题:MySQL:什么是LIKE的反向版本?.应该也适用于PostgreSQL(尚未测试过).

请注意,您可以将查询调整为可重用的自定义Lookup(在Django 1.7中引入):

  • 想象你有以下模型

    class MyModel(models.Model):
        name = models.CharField(max_length=100)
    
        def __unicode__(self):
            return self.name
    
    Run Code Online (Sandbox Code Playgroud)
  • Lookup使用as_sql()实现的方法定义类:

    class ConverseEndswith(models.Lookup):
        lookup_name = 'ce'
    
        def as_sql(self, qn, connection):
            lhs, lhs_params = self.process_lhs(qn, connection)
            rhs, rhs_params = self.process_rhs(qn, connection)
            params = lhs_params + rhs_params
            return '%s LIKE CONCAT("%%%%", %s)' % (rhs, lhs), params
    
    models.Field.register_lookup(ConverseEndswith)
    
    Run Code Online (Sandbox Code Playgroud)
  • 那么,这是我们的自定义__ce查找的工作方式shell:

    >>> import django
    >>> django.setup()
    >>> from myapp.models import MyModel
    >>> for name in ['hello', 'ello', 'llo', 'test1', 'test2']:
    ...     MyModel.objects.create(name=name)
    
    >>> MyModel.objects.filter(name__ce='hello')
    [<MyModel: hello>, <MyModel: ello>, <MyModel: llo>]
    >>> MyModel.objects.filter(name__ce='hello').query.__str__()
    u'SELECT `myapp_mymodel`.`id`, `myapp_mymodel`.`name` FROM `myapp_mymodel` WHERE hello LIKE CONCAT("%", `myapp_mymodel`.`name`)'
    
    Run Code Online (Sandbox Code Playgroud)

另一个选择是在Python中进行检查.由于LIKE查询将对Entry表中的所有记录进行全面扫描,因此您可以使用Python获取所有记录并逐个检查endswith():

[entry for entry in Entry.objects.all() if 'hello'.endswith(entry.name)]    
Run Code Online (Sandbox Code Playgroud)