Django原始SQL-左外部联接效率和更好的方法?
我正在尝试3个表的外部联接,想知道我的方法是否正确有效 型号:Django原始SQL-左外部联接效率和更好的方法?,sql,django,django-templates,django-views,Sql,Django,Django Templates,Django Views,我正在尝试3个表的外部联接,想知道我的方法是否正确有效 型号: class GuestCategory(models.Model): profile = models.ForeignKey(UserProfile) category = models.CharField(max_length=30) class Meta: db_table = 'guest_category' class Guest(models.Model): profil
class GuestCategory(models.Model):
profile = models.ForeignKey(UserProfile)
category = models.CharField(max_length=30)
class Meta:
db_table = 'guest_category'
class Guest(models.Model):
profile = models.ForeignKey(UserProfile)
guest_category = models.ForeignKey(GuestCategory,
null=True, blank=True, default = None)
first_name = models.CharField(max_length=48, blank=False)
last_name = models.CharField(max_length=48)
invite_list = models.ManyToManyField(GuestList, through='RSVPList')
class Meta:
ordering = ('last_name', 'first_name')
db_table = 'guest'
class GuestDetails(models.Model):
guest = models.OneToOneField(Guest)
email = models.EmailField(max_length=254, blank=True)
...
country = models.IntegerField(choices=Country(), null=True, blank=True)
class Meta:
db_table = 'guest_details'
观点:
class GuestListView(LoginRequiredMixin, ListView):
context_object_name = 'guest_list'
template_name = 'guest/guest_list.html'
def get_queryset(self):
self.guests = Guest.objects.raw("SELECT \
guest.id, \
guest.first_name, \
guest.last_name, \
guest_details.email, \
...
guest_details.country, \
guest_category.category \
FROM guest \
LEFT OUTER JOIN guest_details \
ON guest_details.guest_id = guest.id \
LEFT OUTER JOIN guest_category \
ON guest_category.id = guest.guest_category_id \
WHERE guest.profile_id = %s", [self.request.user.get_profile().id]
)
return self.guests
模板:
<ul>
{% for guest in guest_list %}
<li>{{ guest.first_name }} {{ guest.last_name }}
<ul>
<li>Email: {{ guest.email }}</li>
...
<li>Country: {{ guest.country }}</li>
{% comment %} {{ guest_details.get_country_display }} {% endcomment %}
<li>Category: {{ guest.guest_category }}</li>
<li><a href="{% url 'guests:guest_update' pk=guest.pk %}">Edit</a></li>
<li><a href="{% url 'guests:guest_delete' pk=guest.pk %}">Remove</a></li>
</ul>
</li>
{% endfor %}
</ul>
注意,来宾类别也不是必填字段。我使用了左侧外部联接来获取类别和详细信息。但是,当我在浏览器中加载视图时,我注意到由于{{{guest.guest_category}
的原因,每个来宾类别的数据库都会被命中。我是否可以从guest_category表中检索类别,而不必像上面的SQL结果那样求助于额外的数据库命中
有没有更好的方法来实现我的目标?我对SQL并不陌生,但如果缓存中有更多类似django的东西,那就太棒了。事实上,我意识到,
预取相关的
是有效的。我对我的模型做了一些更改:
class GuestDetails(models.Model):
guest = models.OneToOneField(Guest, related_name='details')
...
然后在视图中:
guest_list = Guest.objects.filter(profile=profile).prefetch_related('details')
在模板中引用很容易:
{% for g in guests %}
<li>{{ g.full_name }}</li>
<ul>
<li>Category: {{ g.category }}</li>
<li>Email: {{ g.details.email }}</li>
<li>Country: {{ g.details.get_country_display }}</li>
</ul>
{% endfor %}
{%g在来宾%}
{{g.全名}
- 类别:{{g.Category}
- 电子邮件:{{g.details.Email}
- 国家:{{g.details.get_Country_display}
{%endfor%}
但是,在模板中返回g.category
,每次都会命中数据库。需要重新访问
{% for g in guests %}
<li>{{ g.full_name }}</li>
<ul>
<li>Category: {{ g.category }}</li>
<li>Email: {{ g.details.email }}</li>
<li>Country: {{ g.details.get_country_display }}</li>
</ul>
{% endfor %}