简体   繁体   中英

django - inner join queryset not working

The SQL I want to accomplish is this -

SELECT jobmst_id, jobmst_name, jobdtl_cmd, jobdtl_params FROM jobmst
INNER JOIN jobdtl ON jobmst.jobdtl_id = jobdtl.jobdtl_id
WHERE jobmst_id = 3296

I've only had success once with an inner join in django off of a annote and order_by but I can't seem to get it to work doing either prefetch_related() or select_related()

My models are as so -

class Jobdtl(models.Model):
    jobdtl_id = models.IntegerField(primary_key=True)
    jobdtl_cmd = models.TextField(blank=True)
    jobdtl_fromdt = models.DateTimeField(blank=True, null=True)
    jobdtl_untildt = models.DateTimeField(blank=True, null=True)
    jobdtl_fromtm = models.DateTimeField(blank=True, null=True)
    jobdtl_untiltm = models.DateTimeField(blank=True, null=True)
    jobdtl_priority = models.SmallIntegerField(blank=True, null=True)
    jobdtl_params = models.TextField(blank=True) # This field type is a guess.
    class Meta:
        managed = False
        db_table = 'jobdtl'

class Jobmst(MPTTModel):
    jobmst_id = models.IntegerField(primary_key=True)
    jobmst_type = models.SmallIntegerField()
    jobmst_prntid = TreeForeignKey('self', null=True, blank=True, related_name='children', db_column='jobmst_prntid')
    jobmst_name = models.TextField(db_column='jobmst_name', blank=True)
#    jobmst_owner = models.IntegerField(blank=True, null=True)
    jobmst_owner = models.ForeignKey('Owner', db_column='jobmst_owner', related_name = 'Jobmst_Jobmst_owner', blank=True, null=True)
    jobmst_crttm = models.DateTimeField()
    jobdtl_id = models.ForeignKey('Jobdtl', db_column='jobdtl_id', blank=True, null=True)
    jobmst_prntname = models.TextField(blank=True)
    class MPTTMeta:
        order_insertion_by = ['jobmst_id']
    class Meta:
        managed = True
        db_table = 'jobmst'

I have a really simple view like so -

# Test Query with Join
def test_queryjoin(request):
    queryset = Jobmst.objects.filter(jobmst_id=3296).order_by('jobdtl_id')
    queryresults = serializers.serialize("python", queryset, fields=('jobmst_prntid', 'jobmst_id', 'jobmst_prntname', 'jobmst_name', 'jobmst_owner', 'jobdtl_cmd', 'jobdtl_params'))
    t = get_template('test_queryjoin.html')
    html = t.render(Context({'query_output': queryresults}))
    return HttpResponse(html)

I've tried doing a bunch of things -

queryset = Jobmst.objects.all().prefetch_related()

queryset = Jobmst.objects.all().select_related()

queryset = jobmst.objects.filter(jobmst_id=3296).order_by('jobdtl_id')

a few others as well I forget.

Each time the json I'm getting is only from the jobmst table with no mention of the jobdtl results which I want. If I go the other way and do Jobdtl.objects.xxxxxxxxx same thing it's not giving me the results from the other model.

To recap I want to display fields from both tables where a certain clause is met.

What gives?

Seems that I was constantly looking in the wrong place. Coming from SQL I kept thinking in terms of inner joining tables which is not how this works. I'm joining the results from models.

Hence, rethinking my search I came across itertools and the chain function.

I now have 2 queries under a def in my views.py

from itertools import chain

jobmstquery = Jobmst.objects.filter(jobmst_id=3296)
jobdtlquery = Jobdtl.objects.filter(jobdtl_id=3296)
queryset = chain(jobmstquery, jobdtlquery)
queryresults = serializers.serialize("python", queryset)

That shows me the results from each table "joined" like I would want in SQL. Now I can focus on filtering down the results to give me what I want.

Remember folks, the information you need is almost always there, it's just a matter of knowing how to look for it :)

What you are looking for might be this

queryset = Jobmst.objects.filter(id=3296).values_list(
    'id', 'name', 'jobmst_owner__cmd', 'jobmst_owner__params')

You would get your results with only one query and you should be able to use sort with this.

PS Coming from SQL you might find some great insights playing with queryset.query (the SQL generated by django) in a django shell.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM