【问题标题】:Raw query results multiplies many times when I use INNER JOIN in Django当我在 Django 中使用 INNER JOIN 时,原始查询结果成倍增加
【发布时间】:2021-11-15 03:40:20
【问题描述】:

我不明白为什么我的原始查询将结果乘以与用户数量一样多的倍数。我正在使用 INNER JOIN 并且我绑定了两个对象,所以我真的无法得到它。 (我在 Django 查询语言方面没有经验,所以我使用的是原始查询)。

views.py

def index(request):
    projekt = Projekt.objects.raw('SELECT  projekt_id, stressz_projekt.projekt, last_name, first_name, stressz_profile.id, stressz_profile.user_id, auth_user.id FROM stressz_profile INNER JOIN stressz_projekt ON stressz_projekt.id = stressz_profile.projekt_id INNER JOIN auth_user ON auth_user.id = stressz_profile.user_id')

    template = loader.get_template('stressz/index.html')

    context = {
        'projekt': projekt,
    }
    return HttpResponse(template.render(context, request))

如果我使用 Django ORM,我会得到相同的结果

profile = Profile.objects.get(user=request.user)
projekt = Profile.objects.filter(projekt=profile.projekt)

models.py

class Viselkedestipus(models.Model):

    def __str__(self):
        return str(self.user_name)

        user_name = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
        date = models.DateField(auto_now_add=True, auto_now=False, blank=True)


class Profile(models.Model):

    def __str__(self):
        return str(self.user)

    user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
    date = models.DateField(auto_now_add=True, auto_now=False, blank=True)
    projekt = models.ForeignKey(Projekt, on_delete=models.CASCADE, default=1)


class Projekt(models.Model):

    def __str__(self):
        return str(self.projekt)

    projekt = models.TextField(max_length=150)
    company_name = models.ForeignKey('Company', on_delete=models.CASCADE, default=1)
    date = models.DateField(auto_now_add=True, auto_now=False, blank=True)

【问题讨论】:

  • 为什么不使用 Django ORM?如果您共享您的 models.py 文件,我们可以提供帮助。
  • 嗨丹尼尔!谢谢,我编辑并放入models.py。我不使用 ORM,因为我不熟悉它。

标签: python sql django


【解决方案1】:

下面是一个简单的例子,说明如何使用可以适应你的情况的 ORM:

假设我们有两个模型,CountryCity,如下所示:

class Country(models.Model):

    """ country model """

    name = models.CharField(...)


class City(models.Model):

    """ city model with a foreign key to a country """

    country = models.ForeignKey('Country', ..., related_name='cities')
    name = models.CharField(...)
    population = models.PositiveIntegerField(...)

我们可以按如下方式使用 Django ORM:

# filter for a country with a given name:
country = Country.objects.filter(name='Italy')
country.name # Italy

# filter for a city with a given name:
city = City.objects.filter(name='Rome')
city.name # Rome

# get the country the city belongs to:
country = city.country
country.name # Italy

# get the queryset of all cities with a population greater than 1 million in a specific country:
country = Country.objects.filter(name='Italy')
large_cities = country.cities.filter(population__gt=1000000)
for city in large_cities:
    print(city.name)   
# loop will print: Rome, Milan

此外,您似乎只是将Projeckt 实例传递给您的模板。所以你真的不需要 ORM,相反你可以这样做:

我还将简要补充一下,您似乎已经颠倒了配置文件-项目的关系 - 因为它代表一个配置文件只能有一个项目,但一个项目可以有多个配置文件 - 不确定这是否是故意的。

views.py

def index(request):

    # get projekt by id:
    projekt = Projekt.objects.get(id=<the-id>)

    template = loader.get_template('stressz/index.html')

    context = {
        'projekt': projekt,
    }
    return HttpResponse(template.render(context, request))

然后在您的模板中: stressz/index.html

<!-- use context data in template -->
<div> Name: {{projekt.projekt}} </div>

<!-- loop over all profiles in the project -->
{% for profile in projekt.profile_set %}
  <div> User First Name: {{ profile.user.first_name }} </div>
  <div> User Last Name: {{ profile.user.last_name}} </div>
{% endfor %}

【讨论】:

    猜你喜欢
    • 2017-05-13
    • 1970-01-01
    • 2013-11-18
    • 2016-01-02
    • 2011-12-22
    • 2016-08-29
    • 2021-12-26
    • 1970-01-01
    • 2017-04-24
    相关资源
    最近更新 更多