【问题标题】:Django 3.2 - raw-SQL-Query with same table (Model)Django 3.2 - 具有相同表的原始 SQL 查询(模型)
【发布时间】:2022-01-11 13:14:40
【问题描述】:

我们已将一些数据库表从我们的生产环境迁移到 django ORM,并在 django 之外自动同步这些表。 → 到目前为止效果很好,但是我们在 django 中无法正确连接这些表(模型)。

models.py

class SsdaSdgadr(models.Model):
    sda_sdgid = models.ForeignKey(SsdgSendung, on_delete=models.CASCADE, blank=True, null=True)
    sda_satid = models.CharField(max_length=4, blank=True, null=True)
    sda_adrid = models.ForeignKey(SadrAdresse, on_delete=models.CASCADE, blank=True, null=True)
    sda_ref = models.CharField(max_length=35, blank=True, null=True)
    sda_termbis = models.DateField(blank=True, null=True)
    sda_termvon = models.DateField(blank=True, null=True)

    class Meta:
        db_table = 'ssda_sdgadr'
        unique_together = (('sda_sdgid', 'sda_satid'),)

class SsdgSendung(models.Model):
    sdg_sdgid = models.CharField(primary_key=True, max_length=30)
    sdg_konz = models.CharField(max_length=12, blank=True, null=True)

    class Meta:
        db_table = 'ssdg_sendung'

class SadrAdresse(models.Model):
    adr_adrid = models.IntegerField(primary_key=True)
    adr_name1 = models.CharField(max_length=35, blank=True, null=True)
    adr_name2 = models.CharField(max_length=35, blank=True, null=True)

    class Meta:
        db_table = 'sadr_adresse'

样本数据

SsdaSdgadr:

sdg_sdgid sda_satid sda_adrid sda_ref sda_termvon sda_termbis
BL-1237781-BL-1 IV 169550 '00123/4539999' '' ''
BL-1237781-BL-1 SU 555555 '' 01.12.2021 02.12.2021
BL-1237781-BL-1 CN 999999 '00123' 02.12.2021 13.12.2021

views.py

我使用以下原始 SQL

    Sendungen = SsdaSdgadr.objects.raw('''
        SELECT 
            IV.id,
            IV.sda_sdgid_id,
            IV.sda_ref,
            SU.id,
            SU.sda_adrid_id as ABS,
            SU.sda_termvon,
            CN.id,
            CN.sda_adrid_id as EMPF,
            CN.sda_termbis
        FROM 
            ssda_sdgadr IV
            INNER JOIN ssdg_sendung on sdg_sdgid = IV.sda_sdgid_id
            INNER JOIN ssda_sdgadr SU on SU.sda_sdgid_id = IV.sda_sdgid_id and SU.sda_satid="SU"
            INNER JOIN ssda_sdgadr CN on CN.sda_sdgid_id = IV.sda_sdgid_id and CN.sda_satid="CN"
        WHERE IV.sda_satid="IV"
        GROUP BY
            IV.id,
            IV.sda_sdgid_id,
            IV.sda_ref,
            SU.id,
            SU.sda_adrid_id,
            SU.sda_termvon,
            CN.id,
            CN.sda_adrid_id,
            CN.sda_termbis
        ORDER BY
            sdg_datum desc
    ''')
...
response = render(request, 'cust/home.html', {
            'Sendungen': Sendungen,
        })
return response

模板上的结果适用于字段“SU.sda_termvon”和“CN.sda_termbis”,但不适用于字段“sda_adrid”(→ 仅显示 IV.sda_adrid_id 的结果)。

模板代码

 {% for la_item in Sendungen %}
                        <tr>
                            <td>{{ la_item.sda_sdgid.sdg_sdgid }}</td>
                            <td>{{ la_item.sda_ref }}</td> <!-- IV.sda_ref OKAY -->
                            <td>{{ la_item.sda_adrid.adr_adrid }}</td> <!-- is IV.sda_adrid NOT OKAY -->
                            <td>{{ la_item.sda_adrid.adr_adrid }}</td> <!-- is IV.sda_adrid NOT OKAY -->
                            <td>{{ la_item.sda_termvon|date }}</td> <!-- SU.sda_termvon OKAY -->
                            <td>{{ la_item.sda_termbis|date }}</td> <!-- CN.sda_termbis OKAY -->
                        </tr>
 {% endfor %}

如何访问模板上的结果“CN.sda_adrid_id”和“SU.sda_adrid_id”? → 看起来 ORM 对原始 SQL 的解释与数据库不同:

DB-Result & Desired result 应该如下所示:

sda_sdgid_id IV.sda_ref SU.sda_adrid_id CN.sda_adrid SU.termvon CN.termbis
BL-1237781-BL-1 1920192/4530210220/0881760357 555555 999999 01.12.2021 13.12.2021

我的实际结果是这样的:

sda_sdgid_id IV.sda_ref IV.sda_adrid_id IV.sda_adrid_id SU.termvon CN.termbis
BL-1237781-BL-1 1920192/4530210220/0881760357 169550 169550 01.12.2021 13.12.2021

【问题讨论】:

    标签: django django-models django-views django-templates


    【解决方案1】:

    我使用了这个解决方法(“SsdaSdgadr”的模型属性),它给了我想要的结果:

    models.py

    class SsdaSdgadr(models.Model):
        sda_sdgid = models.ForeignKey(SsdgSendung, on_delete=models.CASCADE, blank=True, null=True)
        sda_satid = models.CharField(max_length=4, blank=True, null=True)
        sda_adrid = models.ForeignKey(SadrAdresse, on_delete=models.CASCADE, blank=True, null=True)
        sda_ref = models.CharField(max_length=35, blank=True, null=True)
        sda_termbis = models.DateField(blank=True, null=True)
        sda_termvon = models.DateField(blank=True, null=True)
    
        class Meta:
            db_table = 'ssda_sdgadr'
            unique_together = (('sda_sdgid', 'sda_satid'),)
    
        @property
        def is_adr_su(self):
            return  SsdaSdgadr.objects.filter(sda_sdgid = self.sda_sdgid, sda_satid = "SU")
    
        @property
        def is_adr_cn(self):
            return  SsdaSdgadr.objects.filter(sda_sdgid = self.sda_sdgid, sda_satid = "CN")
    

    views.py

    Sendungen = SsdaSdgadr.objects.filter(Q(sda_satid__in=["IV"])).order_by('-sda_sdgid__sdg_datum')
    ...
    response = render(request, 'cust/home.html', {
                'Sendungen': Sendungen,
            })
    return response
    

    模板代码 home.html

    {% for la_item in Sendungen %}
    <tr>
     <td>{{ la_item.sda_sdgid.sdg_sdgid }}</td>
     <td>{{ la_item.sda_ref }}</td> <!-- IV.sda_ref OKAY -->
     {% for adr in la_item.is_adr_su %}
       <td>{{ adr.sda_adrid.adr_adrid }}</td> <!-- SU.sda_adrid OKAY -->
       <td>{{ adr.sda_termvon|date }}</td> <!-- SU.sda_termvon OKAY -->
     {% endfor %}
     {% for adr in la_item.is_adr_cn %}
       <td>{{ adr.sda_adrid.adr_adrid }}</td> <!-- CN.sda_adrid OKAY -->
       <td>{{ adr.sda_termbis|date }}</td> <!-- CN.sda_termbis OKAY -->
     {% endfor %}
    </tr>
    {% endfor %}
    

    【讨论】:

      猜你喜欢
      • 2015-11-21
      • 2012-03-16
      • 2017-05-04
      • 2013-04-17
      • 2018-05-15
      • 2011-06-24
      • 1970-01-01
      • 2021-10-01
      • 2015-03-22
      相关资源
      最近更新 更多