Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django原始SQL-左外部联接效率和更好的方法?_Sql_Django_Django Templates_Django Views - Fatal编程技术网

Django原始SQL-左外部联接效率和更好的方法?

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

我正在尝试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):
    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 %}