簡體   English   中英

Django:將第二個查詢集的結果添加到第一個查詢集

[英]Django: Add result from second queryset to first queryset

我有來自兩個不同數據庫的兩個模型(一個只讀),兩個模型之間沒有 ForeignKey(沒有得到那個工作,因為我發現這是不可能的)。 在主 model 中,我存儲來自第二個 model(只讀 DB)的 ID。 我想在一個視圖上顯示多個記錄/行(如 al 表),因為我想獲取第二個 model 的內容,其 id 來自主 model。 並將其合並為一行。 正常情況下,您可以通過 ForeignKey 獲取它,但不會與 2 個不同的數據庫一起使用。

我得到了什么(簡化):

model.py

class Overeenkomst(models.Model):
    park = models.IntegerField(blank=False, null=False, default='0')
    object = models.IntegerField(blank=False, null=False, default='0')  # ID from model second database  
    date_start = models.DateField()
    date_end = models.DateField()


class Object(models.Model):
    id = models.IntegerField(db_column='ID', primary_key=True)  # Field name made lowercase.
    nummer = models.IntegerField(db_column='NUMMER', blank=True, null=True)  # Field name made lowercase.
    omschrijving = models.CharField(db_column='OMSCHRIJVING', max_length=50, blank=True, null=True)  # Field name made lowercase.
    idobjectsoort = models.IntegerField(db_column='IDOBJECTSOORT', blank=True, null=True)  # Field name made lowercase.
    idobjecttype = models.IntegerField(db_column='IDOBJECTTYPE', blank=True, null=True)  # Field name made lowercase.
    (.....)

    class Meta:
        managed = False
        db_table = 'OBJECT'
        unique_together = (('nummer', 'idpark', 'id'), ('id', 'idpark', 'idobjecttype', 'idobjectsoort', 'dubbelboeking'), ('code', 'id'),)


    def __str__(self):
        return self.omschrijving

視圖.py

def ovk_overview(request):
    ctx={}

    overeenkomsten =models.Overeenkomst.objects.filter(park=request.session['park_id'])

    ovk = []
    for overeenkomst in overeenkomsten:
        obj = models.Object.objects.using('database2').filter(pk=overeenkomst.object).values('omschrijving')
        
        ##### Here I Missing a part #####
        

    ctx['overeenkomsten'] = ovk
    return render(request, 'overeenkomsten/overzicht.html', context=ctx)

overzicht.html

{% extends "base.html" %}
{% load static %}

{% block content %} 
<table class='table table-sm'>
    <tr>
        <th>#</th>
        <th>Object</th>
        <th>Start datum</th>
        <th>Eind datum</th>
        <th>&nbsp;</th>
    </tr>

    {% for ovk in overeenkomsten %}
    {{ ovk }}::
    <tr>
        <td>{% now 'Y' %}{{ ovk.park }}{{ovk.object}}{{ovk.id}}</td>
        <td>{{ ovk.object.omschrijving}}</td>
        <td>{{ ovk.date_start|date:"d-m-Y" }}</td>
        <td>{{ ovk.date_end|date:"d-m-Y" }}</td>
        <td><a href="{% url 'overeenkomsten:pdf_vast' ovk.id %}" target="_blank"><button class="btn btn-primary">Download pdf</button></a></td>
    </tr>
    {% endfor %}
</table>
{% endblock %}

I have tried to use list() and chain() (as answer https://stackoverflow.com/a/8171434 ) but then i get only the values of the Object model and nothing from the Overeenkomsten model.

我希望有人對我有答案/想法。

你可以做這樣的事情。

視圖.py

from django.forms.models import model_to_dict 

    def ovk_overview(request):
        ctx={}
    
        overeenkomsten =models.Overeenkomst.objects.filter(park=request.session['park_id'])
    
        ovk = []
        for overeenkomst in overeenkomsten:
            overeenkomst_dict = model_to_dict(overeenkomst)
            obj = models.Object.objects.using('database2').get(pk=overeenkomst.object) #Assumed there is always an obj. If not, change accordingly.
            overeenkomst_dict['omschrijving'] = obj.omschrijving
            ovk.append(overeenkomst_dict) 
            
            
            
    
        ctx['overeenkomsten'] = ovk
        return render(request, 'overeenkomsten/overzicht.html', context=ctx)

overzicht.html

{% extends "base.html" %}
{% load static %}

{% block content %} 
<table class='table table-sm'>
    <tr>
        <th>#</th>
        <th>Object</th>
        <th>Start datum</th>
        <th>Eind datum</th>
        <th>&nbsp;</th>
    </tr>

    {% for ovk in overeenkomsten %}
    {{ ovk }}::
    <tr>
        <td>{% now 'Y' %}{{ ovk.park }}{{ovk.object}}{{ovk.id}}</td>
        <td>{{ ovk.omschrijving }}</td>
        <td>{{ ovk.date_start|date:"d-m-Y" }}</td>
        <td>{{ ovk.date_end|date:"d-m-Y" }}</td>
        <td><a href="{% url 'overeenkomsten:pdf_vast' ovk.id %}" target="_blank"><button class="btn btn-primary">Download pdf</button></a></td>
    </tr>
    {% endfor %}
</table>
{% endblock %}

首先,一個警告。 不要調用字段objectid 它們不是 Python 保留字,但使用它們會覆蓋 Python 通常提供的含義。 這真是令人困惑,尤其是在object的情況下,如果您開始使用基於類的視圖和 Mixins,以后也可能會給您帶來痛苦的世界。 所以稱他們為something_id ,或者只是obj

好的。 一個想法……是的。 這取決於有足夠的 memory 將主查詢集轉換為對象列表。 然后,您使用來自第二個數據庫中相應對象的數據“注釋”第一個列表中的對象。

我在下面用other_id替換了object ,因為我根本想不到原來的名字。 就像用紅色墨水打印的藍色。

    # query the first DB. You might want to chheck that the length
    # of the query is sensible, and/or slice it with a maximum length

    overeenkomsten  = models.Overeenkomst.objects.filter(park=request.session['park_id'])
    if overeenkomsten.count() > MAX_OBJECTS: # shouldn't ever happen
        # do something to save our server!
        overeenkomsten = overeenkomsten[:MAX_OBJECTS]

    # fetch all the data
    overeenkomsten = list(  overeenkomsten )

    # get the required data from the other DB. 
    # One query, retaining pk to tie the two together. 
    # avoids N queries on second DB

    other_db_ids = [ x.other_id for x in  overeenkomsten ]  # was x.object
    data_from_other_db = models.Object.objects.using('database2'
        ).filter(pk__in = other_db_ids
        ).values_list('pk', 'omschrijving'
        )

    # convert to a dict. This way for clarity and because I can't remember the dict method 
    #for converting a list of key/value pairs into a dict.

    omschrivings = {}
    for k,v in data_from_other_db:
         omschrivings[k] = v

    # "Annotate" the objects from the first query with the data from the second. 
    # It's read-only so no need to worry about saving it should somebody update it.
    # (but you could subclass the save method if it wasn't)

    for obj in overeenkomsten:
       setattr( obj, 'omschriving', omschrivings[ obj[x.other_id] ] )

在模板中,只是

<td>{{ ovk.omschrijving}}</td>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM