Django:在对象创建后查询M2M表返回空数组

时间:2018-02-27 05:09:47

标签: django python-3.x django-models

我使用Django信号在使用post_save保存模型后运行代码块。 post_save中的信号接收器获取对象的实例,在实例通过网络发送给第三方之前将其发送到某个方法进行某些处理。

我的一个模型foo与另一个模型bar有多对多的关系,我需要在向第三方发送foo之前添加一个名为bar_id的数组,其中包含每个条的ID。

此配置在更新foo实例时有效,但是当我创建foo的新实例并查询其关系时(请参阅添加栏ID的麻烦查询)为了将Foo发送到第三方部分,即使数据库中存在关系,查询也会返回一个空查询集。如果我稍后更新相同的模型,这个完全相同的查询将返回一个查询集。

为什么会出现这种情况的任何想法?

以下是代码:

注册信号

来自django.apps导入AppConfig

class FooConfig(AppConfig):
    name = 'foo'

    def ready(self):
        import foo.signals

信号代码

from django.dispatch import receiver
from django.db.models.signals import post_save
from django.conf import settings
from django.db.models import F
from .models import Foo
from utils import search

def my_handler(sender, **kwargs):
    table_name = 'foo'
    instance = kwargs.get('instance', None)
    foo = Foo.objects.filter(id=instance.id).annotate(objectID=F('id')).values()[0]
    if kwargs.get('created', True):
        search.add_object(table_name, foo, instance.id)
    elif not kwargs.get('created', False):
        search.update_object(table_name, foo)

post_save.connect(my_handler, sender=Foo)

将条形码添加到Foo并发送给第三方

def add_object(table_name, instance, pk):
    from foo.models import Foo

    env = settings.ENVIRONMENT
    # init client
    client = algoliasearch.Client('key', settings.ALGOLIA_KEY)
    # init index that object will be added to
    index = client.init_index(env + "_" + table_name)

    if table_name == 'foo':
        # the troublesome query 
        bar = Foo.bar.through.objects.filter(foo_id=pk)
        instance['bar_id'] = []
        print('pre loop')
        for k in bar:
            print('for loop entered')
            instance['bar_id'].append(k.get('bar_id'))

1 个答案:

答案 0 :(得分:0)

假设你有这样的模特,那么

class Bar(models.Model):
    # some fields


class Foo(models.Model):
    # some fields
    bar = models.ForeignKey(Bar)


然后,

bar_ids = Foo.objects.filter(id=foo_id).values_list('bar_id',flat=True)

其中foo_idid个实例的Foo

示例:

bar_ids = Foo.objects.filter(id=1).values_list('bar_id',flat=True)