Joseph
Joseph

Reputation: 13178

Django: Use select_related without a ForeignKey field

I have two models which are used with a database I don't control. Both are set with managed = False. The first model has a field which is a foreign key to the second model, but it's implemented as a CharField, not as a ForeignKey.

Is it possible to use select_related on the first model to access properties of the key'd second model?

Here's an example:

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? 

Upvotes: 5

Views: 4537

Answers (1)

Gocht
Gocht

Reputation: 10256

No, because there's nothing related.

But if you (or someone for some reason) have stored the ID (or some unique value such as localkey) from the 'related' object, you could perform a filter based on it.

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

To make this looks like select_related you could try this:

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

Then use like this:

foos = Foo.objects.all()

for foo in foos:
    print foo.bar()

I am not sure if this is a good idea but you could decorate .bar() method as a property:

...

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

And then call it like this:

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

Upvotes: 0

Related Questions