Django:连接两个表

Django: join two tables

这是我目前拥有的:

class Sessions(models.Model):
    sessionId = models.AutoField(primary_key=True)

class Ip(models.Model):
    ipId = models.AutoField(primary_key=True)

class Affiliation(models.Model):
    affiliationId = models.AutoField(primary_key=True)
    ip = models.ForeignKey("Ip", null=False, db_column="ipId")
    session = models.ForeignKey("Sessions", null=False, db_column="sessionId")

现在我想找到 returns ipId=x 的 Sessions QuerySet。基本上这就是我正在尝试的:

Sessions.objects.filter(affiliation__ip=x)

有什么方法可以在 django 中做到这一点吗?

重构您的代码

抱歉,请多包涵,吸取教训

You don't have to explicitly specify the id in Django. unless your class is unmanaged. Django automatically use id or pk to refer to it.

class Sessions(models.Model):
    pass

Model naming usually Singular Session.

class Session(models.Model):
    pass

Watch out for conflict model name, Session is already used internally by Django django.contrib.sessions.models.Session. Use alternative name such as ClientSession would be better.

class ClientSession(models.Model):
    pass

Use ManyToManyField (optional), it is just a helper to simplify your queryset.

class ClientSession(models.Model):
    client_source = models.ManyToManyField('IP', through='Affiliation')

Use GenericIPAddressField

class IP(models.Model):
    address = models.GenericIPAddressField()

You have no additional attribute in Affiliation, thus you can consider removing it.

class ClientSession(models.Model):
    client_source = models.ManyToManyField('IP')

最终模型

class ClientSession(models.Model):
    client_source = models.ManyToManyField('IP')

class IP(models.Model):
    address = models.GenericIPAddressField()

回答

Querying Session is very straight forward with the current Model.

x = 1 # Some ID
ClientSession.objects.filter(ips__id=x)

找到答案了!

psobjs = Affiliation.objects.filter(ipId=x)
queryset = Sessions.objects.filter(sessionId__in=psobjs.values('sessionId'))

我想如果你在这样的联盟模型中使用 related_name:

class Sessions(models.Model):
    sessionId = models.AutoField(primary_key=True)

class Ip(models.Model):
    ipId = models.AutoField(primary_key=True)

class Affiliation(models.Model):
    affiliationId = models.AutoField(primary_key=True)
    ip = models.ForeignKey("Ip", null=False, db_column="ipId")
    session = models.ForeignKey(
        "Sessions", null=False, 
        db_column="sessionId", 
        related_name="affiliation_session"
    )

现在您可以过滤:

Sessions.objects.filter(affiliation_session__ip_id=X)

必要时可以使用select_related进行优化

我想在 customer_name、mobile_no、详细信息 table 和状态 table 中显示报告。你可以看到我的模型

class Details(models.Model):
    customer_name = models.CharField(max_length=100,unique=True)
    mobile_no = models.IntegerField()

class Status(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    status = models.CharField(max_length=25)
    purchase = models.ForeignKey(Details, null=True, on_delete=models.SET_NULL)

解决方案

第 1 步:将以下代码添加到您的视图中。 [views.py]

def customer_report(request):
    status_obj = Status.objects.all()
    return render('reports/customer_report.html', {'status_obj':status_obj})

第 2 步:在您的模板端添加以下代码 [report.html]

<table class="table">
    <thead>
      <tr>
        <th>Name</th>
        <th>Mobile No</th>
        <th>Status</th>
      </tr>
    </thead>
    <tbody>
        {% for data in status_obj  %}
          <tr>
            <td>{{data.purchase.customer_name}}</td>
            <td>{{data.purchase.mobile_no}}</td>
            <td>{{data.status}}</td>
          </tr>
        {% endfor %}
    </tbody>
</table>