2017-07-06 128 views
1

我的生产服务器上有一个奇怪的行为。当我试图通过逆转外键过滤,然后我收到一个错误,这是不可能的,但在本地能正常工作,如:Django ORM无法通过反向外键过滤

class Foo(models.Model): 
    pass 

class Bar(models.Model): 
    name = models.CharField() 
    foo = models.ForeignKey('Foo', related_name='bars', blank=True, null=True, default=None) 

现在要做的:

Foo.objects.filter(bars__name=xyz) 

将导致与

无法将关键字'bars'解析为字段。选项包括:...

我使用Ubuntu 16.04和Django的1.8.7

编辑1: 能不能与该ForeignKeys使用字符串表示定义的事实呢?

编辑2: 我发现关系是用class not string来定义的,所以它不适用于这样的关系。

基本上模型Foo有很多ForeignKey的关系。在Foo很少,在目标模型很少。从Foo角度运行查询时,这些目标模型在生产时不存在。这些在Foo可以用作查询参数。

编辑3: 我收到了更详细的服务器配置信息以及何时发生错误。

信息有关的生产设置,其中的问题被认为是:

  • Apache的版本:2.4.18-2ubuntu3.3
  • 中的libapache2-MOD-WSGI版本:4.3.0-1.1build1

阿帕奇mpm_event配置:

StartServers 2 
MinSpareThreads 25 
MaxSpareThreads 75 
ThreadLimit 64 
ThreadsPerChild 25 
MaxRequestWorkers 150 
MaxConnectionsPerChild 0 

Apache站点配置的有关部分:

WSGIDaemonProcess some_name group=some_name maximum-requests=1000 processes=2 threads=15 user=some_name 
WSGIProcessGroup some_name 
WSGIScriptAlias/"/usr/lib/python2.7/dist-packages/some_name/wsgi.py" 
WSGIPassAuthorization On 

基本上每个请求都不会发生错误。当它出现时,它来自一名工人。重新启动Apache修复了一段时间的错误。

其中一个想法是,在加载Django模型时可能存在竞争条件。

+0

的'fk'应该是'Foo'和相关的名称'bars' –

+1

应该是双向的。 Withouth related_name查询应该是过滤器(bar_set__name = xyz) – szaman

+0

什么是更多的本地一切似乎都很好。 – szaman

回答

1

您还没有定义fk正确:

class Foo(models.Model): 
    pass 

class Bar(models.Model): 
    name = models.CharField() 
    foo = models.ForeignKey(Foo, related_name='bars', blank=True, null=True, default=None) 

为了应对进口通告:

foo = models.ForeignKey('<app_name>.Foo', related_name='bars', blank=True, null=True, default=None) 
+1

哦,你是对的,我在伪代码中犯了错误。现在纠正了。 – szaman

+0

Cool =)直接传递'Foo'而不是字符串。 –

+0

有问题,我们有很多的模型,并有循环进口 – szaman

1

您必须在您的查询过滤器中使用related_query_name。默认在Django 1中。8它的型号名称,因此设置自定义related_query_name或更改您的代码如下:

Foo.objects.filter(bar__name=xyz) 
+0

:用于来自目标模型的反向过滤器名称的名称。如果设置,它默认为related_name或default_related_name的值,否则默认为模型的名称。 – szaman

+1

因此它应该与定义的related_name一起工作,但值得尝试。 – szaman

+0

@Dima Kudosh'related_name'绝对有效。这是我在我的代码中始终使用的,从未遇到过问题。 –