【问题标题】:Django inner join methods return unexpected resultsDjango 内部连接方法返回意外结果
【发布时间】:2021-10-28 09:56:54
【问题描述】:

我是 Django 的 ORM 的新手,尽管在 SO 上咨询过 documentationother answers,但我对内部连接约定感到困惑。我有两个表 - MyPointsMyBuffersprojectid 一对一相关(两个表中都没有重复)。我的目标是使用projectid 上的内部连接来获取radius 字段。即使我已经定义了一个外键,我第一次尝试从MyBuffers 获取所有字段都不会从连接表中返回任何内容,而我第二次尝试从MyBuffers 获取一个字段时出现错误。这里的语法或方法有什么问题?键列应该以不同的方式命名吗?任何建议将不胜感激!

models.py

from django.contrib.gis.db import models

class MyBuffers(models.Model):
    id = models.BigAutoField(primary_key=True)
    projectid = models.CharField(max_length=25, unique=True)
    radius = models.IntegerField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'my_buffers'

class MyPoints(models.Model):
    id = models.BigAutoField(primary_key=True)
    projectid = models.ForeignKey('MyBuffers', max_length=25, on_delete=models.DO_NOTHING, to_field='projectid', db_column='projectid')
    geog = models.PointField(geography=True, srid=4326) 

    class Meta:
        managed = False
        db_table = 'my_points'

views.py

from .models import MyPoints
from .models import MyBuffers

1.不返回连接的MyBuffers表中的任何字段

test = MyPoints.objects.select_related('projectid')
test.first().__dict__

{'_state': <django.db.models.base.ModelState object at 0x7f3e21786520>, 'id': 5808, 'projectid_id': 'foobar1', 'geog': <Point object at 0x7f3e21738910>}

2.引发错误

test= MyPoints.objects.select_related('projectid__radius')
test.first().__dict__
django.core.exceptions.FieldError: Non-relational field given in select_related: 'radius'. Choices are: (none)

【问题讨论】:

  • 您可以访问MyBuffers 字段,例如:test.first().projectid.radius。你只是在__dict__ 中看不到projectid
  • 对于第二个错误,select_relatedprefetch_related 仅适用于关系字段(如错误所述),因此它适用于外键字段。您不必指定 __radius,因为它已被 select_related('projectid) 提取

标签: python django django-models django-orm geodjango


【解决方案1】:

我认为选择相关只适用于外键。因此,如果您尝试获取外键以外的字段,则会引发错误。您的查询集必须是

test= MyPoints.objects.select_related('projectid')
# To get radius
test.first().projectid.radius

【讨论】:

    【解决方案2】:
    from django.contrib.gis.db import models
    
    class MyBuffers(models.Model):
        id = models.BigAutoField(primary_key=True)
        projectid = models.CharField(max_length=25, unique=True)
        radius = models.IntegerField(blank=True, null=True)
        class Meta:
           managed = False
           db_table = 'my_buffers'
    
    class MyPoints(models.Model):
        id = models.BigAutoField(primary_key=True)
        projectid = models.ForeignKey('MyBuffers', 
        max_length=25,on_delete=models.CASCADE)
        geog = models.PointField(geography=True, srid=4326) 
        class Meta:
            managed = False
            db_table = 'my_points'
    

    试试下面的代码

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-28
      • 1970-01-01
      • 2017-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多