Django JOIN query without foreign key

半城伤御伤魂 提交于 2019-12-05 06:34:41

No, there isn't an effective way unfortunately.

The .raw() is there for this exact thing. Even if it could it probably would be a lot slower than raw SQL.

There is a blogpost here detailing how to do it with query.join() but as they themselves point out. It's not best practice.

Vasilly.Prokopyev

Just reposting some related answer, so everyone could see it. Taken from here: Most efficient way to use the django ORM when comparing elements from two lists

First problem: joining unrelated models

I'm assuming that your Model1 and Model2 are not related, otherwise you'd be able to use Django's related objects interface. Here are two approaches you could take:

  1. Use extra and a SQL subquery:

    Model1.objects.extra(where = ['field in (SELECT field from myapp_model2 WHERE ...)'])
    

    Subqueries are not handled very efficiently in some databases (notably MySQL) so this is probably not as good as #2 below.

  2. Use a raw SQL query:

    Model1.objects.raw('''SELECT * from myapp_model1
                       INNER JOIN myapp_model2
                       ON myapp_model1.field = myapp_model2.field
                       AND ...''')
    

Second problem: enumerating the result

Two approaches:

  1. You can enumerate a query set in Python using the built-in enumerate function:

    enumerate(Model1.objects.all())
    
  2. You can use the technique described in this answer to do the enumeration in MySQL. Something like this:

    Model1.objects.raw('''SELECT *, @row := @row + 1 AS row
                       FROM myapp_model1
                       JOIN (SELECT @row := 0) rowtable
                       INNER JOIN myapp_model2
                       ON myapp_model1.field = myapp_model2.field
                       AND ...''')
    

The Django ForeignKey is different from SQL ForeignKey. Django ForeignKey just represent a relation, it can specify whether to use database constraints.

Try this:

request_url = models.ForeignKey(UserActivityLink, to_field='url_description', null=True, on_delete=models.SET_NULL, db_constraint=False)

Note that the db_constraint=False is required, without it Django will build a SQL like:

ALTER TABLE `user_activity` ADD CONSTRAINT `xxx` FOREIGN KEY (`request_url`) REFERENCES `user_activity_link` (`url_description`);" 

I met the same problem, after a lot of research, I found the above method.

Hope it helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!