Django:使用select_related而不使用ForeignKey字段

时间:2015-10-22 19:43:06

标签: django django-models django-orm

我有两个与我无法控制的数据库一起使用的模型。两者都设置为managed = False。第一个模型有一个字段,它是第二个模型的外键,但它实现为CharField,而不是ForeignKey

是否可以在第一个模型上使用select_related来访问第二个模型的属性?

以下是一个例子:

class Foo(models.Model):
    class Meta:
        managed = False
    fieldone = models.CharField(max_length=10)
    myfk = models.CharField(max_length=20) # In practice, this points to Bar.localkey

class Bar(models.Model):
    class Meta:
        managed = False
    localkey = models.CharField(max_length=20)
    someotherattribute = models.CharField(max_length=100)

Foo.objects.all().select_related('Bar') # I know this won't work, but is there something that will? 

1 个答案:

答案 0 :(得分:1)

不,因为没有任何关系。

但是,如果您(或出于某种原因的某人)已经存储了相关的ID(或某些唯一值,例如localkey)。对象,您可以根据它执行过滤。

foo = Foo.objects.first()  # Pick one Foo object
foo_bar = Bar.objects.get(localkey=foo.myfk)

要使其看起来像select_related,您可以试试这个:

class Foo(models.Model):
    class Meta:
        managed = False
    fieldone = models.CharField(max_length=10)
    myfk = models.CharField(max_length=20)

    def bar(self):
        return Bar.objects.get(localkey=self.myfk)
        # probably you will need to manage common error when performing a .get()
        # DoesNotExist and MultipleObjectsReturned

然后像这样使用:

foos = Foo.objects.all()

for foo in foos:
    print foo.bar()

我不确定这是不是一个好主意,但您可以将.bar()方法设为property

...

@property
def bar(self):
    return Bar.objects.get(localkey=self.myfk)

然后像这样称呼它:

foo  # some random Foo object
foo.bar  # this should return the 'related' Bar object