Django фильтр запроса, возвращающий значения внешнего ключа - PullRequest
0 голосов
/ 10 марта 2020

Здесь снова вопрос Django. У меня есть следующие модели:

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'

У меня также есть фильтр, объявленный в filters.py с использованием django -filters:

class ServiceFilter(django_filters.FilterSet):

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

фильтр вызывается в представлении :

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

Наконец, файл 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>

Очевидно, что код не будет работать, но я не могу понять, как я должен использовать Django ORM или фильтры для фильтрации набора запросов на основе значений внешнего ключа и отображения значений внешнего ключа, поскольку временная таблица просто используется для связывания внешних ключей.

Я хотел бы получить набор запросов, который выводит эквивалент следующего 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

Не могли бы вы дать некоторое представление о том, как я могу развить это в Django?

ОБНОВЛЕНИЕ: Модели , фильтры, просмотры и html с новой версией.

1 Ответ

0 голосов
/ 11 марта 2020

Хорошо, иногда проще, тем лучше. Поскольку я основан на представлениях базы данных, я решил проблему проектирования, создав окончательное представление в базе данных, а затем создал одну модель:

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'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...