简体   繁体   English

Django过滤器查询集返回外键值

[英]Django filter queryset returning foreign key values

Here again with a Django question.这里又是一个 Django 问题。 I've got models as follows:我有如下模型:

class Host(models.Model):
    id = models.IntegerField(primary_key=True)
    hostname = models.TextField()

    class Meta:
        managed = False
        db_table = 'py_hosts'

class Ip(models.Model):
    id = models.IntegerField(primary_key=True)
    ip = models.TextField()

    class Meta:
        managed = False
        db_table = 'py_ip'

class Port(models.Model):
    id = models.IntegerField(primary_key=True)
    port = models.TextField()

    class Meta:
        managed = False
        db_table = 'py_ports'

class Service(models.Model):
    id = models.IntegerField(primary_key=True)
    host = models.ManyToManyField("Host", through="HostService")
    ip = models.ManyToManyField("Ip", through="HostService")
    port = models.ManyToManyField("Port", through="HostService")
    service = models.TextField()

    class Meta:
        managed = False
        db_table = 'py_services'

    def __str__(self):
        return self.service

class HostService(models.Model):
    id = models.IntegerField(primary_key=True)
    host = models.ForeignKey(Host, on_delete=models.DO_NOTHING)
    ip = models.ForeignKey(Ip, on_delete=models.DO_NOTHING)
    port = models.ForeignKey(Port, on_delete=models.DO_NOTHING)
    service = models.ForeignKey(Service, on_delete=models.DO_NOTHING)

    class Meta:
        managed = False
        db_table = 'py_hostservices'

I also have the filter declared in filters.py using django-filters:我还使用 django-filters 在 filters.py 中声明了过滤器:

class ServiceFilter(django_filters.FilterSet):

    class Meta:
        model = Service
        fields = {
            'host': ['icontains',],
            'ip': ['icontains',],
            'service': ['icontains',],
            'port': ['icontains',],
        }

the filter is called in the view:在视图中调用过滤器:

class ServiceListView(ListView):
    model = Service
    template_name = 'services/service_list.html'

    def get_context_data(self, **kwargs):

        context = super().get_context_data(**kwargs)
        context['filter'] = ServiceFilter(self.request.GET, queryset=self.get_queryset())
        return context

Finally, the html file where the filter is called:最后,调用过滤器的 html 文件:

<div class="container">

    <form method="GET">

        {{ filter.form }}
        <button type="submit" class="default" name="_save">Search</button>
    </form>

    <table border="1">
        <tbody>
            {% for service in filter.qs %}
            <tr>
                <td>{{ service.host }}</td>
                <td>{{ service.ip }}</td>
                <td>{{ service.service }}</td>
                <td>{{ service.port }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>

</div>

Obviously the code won't work, but i can't understand how i should use Django ORM or filters to filter the queryset based on Foreign Key values and show Foreign Key values since the interim table is just used for linking Foreign Keys.显然代码不起作用,但我不明白我应该如何使用 Django ORM 或过滤器来过滤基于外键值的查询集并显示外键值,因为临时表仅用于链接外键。

What i'd like to obtain is a queryset that outputs the equivalent of the following SQL:我想获得的是一个查询集,它输出等效于以下 SQL:

SELECT a.description, b.description, c.description, d.description
  FROM py_hostservices
  JOIN py_services ON py_services.id = py_hostservices.service_id
  JOIN py_ports ON py_ports.id = py_hostservices.port_id
  JOIN py_ip ON py_ip.id = py_hostservices.ip_id
  JOIN py_hosts ON py_hosts.id = py_hostservices.host_id

Could you please give some insight on how I can develop this in Django?您能否就我如何在 Django 中开发此功能提供一些见解?

UPDATE: Models, filters, views and html with new version.更新:新版本的模型、过滤器、视图和 html。

Ok, sometimes simpler is better.好吧,有时候越简单越好。 Since i'm based on database views, i solved the design issue by creating the final view altogether in the database and then created a single model:由于我基于数据库视图,我通过在数据库中完全创建最终视图然后创建单个模型来解决设计问题:

class HostService(models.Model):
    id = models.IntegerField(primary_key=True)
    hostname = models.TextField()
    ip = models.TextField()
    port = models.TextField()
    servicename = models.TextField()

    class Meta:
        managed = False
        db_table = 'py_hostservices'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM