Django:将第二个查询集的结果添加到第一个查询集
Django: Add result from second queryset to first queryset
我有来自两个不同数据库的两个模型(一个只读),两个模型之间没有 ForeignKey(没有得到它的工作,据我所知这是不可能的)。
在主模型中,我存储了第二个模型(只读数据库)的 ID。
我想在一个视图中显示多个 records/rows(比如 al table)
因为我想从主模型中获取带有 id 的第二个模型的内容。
并将其合并为一行。
正常情况下,您可以通过 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
view.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> </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 %}
我尝试使用 list() 和 chain()(作为答案 ),但后来我只得到了对象模型的值,而没有从 Overeenkomsten 模型中得到任何值。
我希望有人给我一个answer/idea。
你可以这样做。
views.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> </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 %}
首先,一个警告。不要调用字段 object
或 id
。它们不是 Python 保留字,但使用它们会覆盖通常由 Python 提供的含义。它非常令人困惑,特别是在 object
的情况下,如果您开始使用基于 Class 的视图和 Mixins,也可能在以后给您带来痛苦。所以称他们为 something_id
,或者只是 obj
。
好的。一个想法......是的。这取决于是否有足够的内存将主查询集转换为对象列表。然后用第二个数据库中相应对象的数据“注释”第一个列表中的对象。
我把下面的object
换成了other_id
,因为我实在想不通原来的名字。就像蓝色
用红色墨水印刷。
# 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>
我有来自两个不同数据库的两个模型(一个只读),两个模型之间没有 ForeignKey(没有得到它的工作,据我所知这是不可能的)。 在主模型中,我存储了第二个模型(只读数据库)的 ID。 我想在一个视图中显示多个 records/rows(比如 al table) 因为我想从主模型中获取带有 id 的第二个模型的内容。 并将其合并为一行。 正常情况下,您可以通过 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
view.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> </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 %}
我尝试使用 list() 和 chain()(作为答案 ),但后来我只得到了对象模型的值,而没有从 Overeenkomsten 模型中得到任何值。
我希望有人给我一个answer/idea。
你可以这样做。
views.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> </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 %}
首先,一个警告。不要调用字段 object
或 id
。它们不是 Python 保留字,但使用它们会覆盖通常由 Python 提供的含义。它非常令人困惑,特别是在 object
的情况下,如果您开始使用基于 Class 的视图和 Mixins,也可能在以后给您带来痛苦。所以称他们为 something_id
,或者只是 obj
。
好的。一个想法......是的。这取决于是否有足够的内存将主查询集转换为对象列表。然后用第二个数据库中相应对象的数据“注释”第一个列表中的对象。
我把下面的object
换成了other_id
,因为我实在想不通原来的名字。就像蓝色
用红色墨水印刷。
# 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>