Храните данные без взаимодействия с пользователем

#python #django #django-models #django-views

Вопрос:

Я хочу хранить данные сетевых устройств с помощью модели Django Device в своей базе данных.

Рабочий процесс

  1. Конфигурация хоста должна быть настроена пользователем внутри представления (модели хоста).
  2. Когда конфигурация хоста завершена, сеть должна быть проверена на наличие устройств (модель устройства).
  3. Данные должны храниться внутри базы данных

Проблема:

Функция create_devices() может вызываться только тогда, когда хост настроен, но if Host.objects.values(): не работает.

  1. Как можно вызвать функцию create_devices() только в том случае, если существует одна модель хоста?
  2. Правильно ли использовать представление для хранения динамических и статических данных в базе данных без взаимодействия с пользователем?

Модели:

 class Host(models.Model):
    hostname = models.CharField(default="noads", max_length=6)
    ipv4_address = models.GenericIPAddressField('IPv4')
    ipv4_subnet = models.GenericIPAddressField('IPv4')
    gateway = models.GenericIPAddressField('IPv4')

class Device(models.Model):
    hostname = models.CharField(max_length=64)
    mac_address = models.CharField(max_length=64)
    ipv4_address = models.GenericIPAddressField('IPv4')
 

Мой Взгляд:

 from webapp.models import Host, Device
from django.views import View
from django.views.generic.detail import DetailView
import multiprocessing.dummy
import multiprocessing

def create_devices():
    """
    Creates DB entry of devices if they dont already exist

    :return: List of mulitple devices stored in objects
    :rtype: list ["Device", "Device", ...]
    """

    available_devices = get_available_devices_in_list()
    arp_table_of_all_hosts = get_arp_table_linux()
    dev_list = []
        
    for deviceip in available_devices:
        #If device already exists in DB continue
        if arp_table_of_all_hosts.get(deviceip):
            if arp_table_of_all_hosts[deviceip] in Device.objects.filter(mac_address = arp_table_of_all_hosts[deviceip]):
                continue
            else:
                devmac = arp_table_of_all_hosts[deviceip]
                devname = "unknown"         #socket.gethostbyaddr(deviceip)
                dev = Device(hostname=devname, mac_address=devmac, ipv4_address=deviceip)
                dev.save()
                dev_list.append(dev)
        
    return dev_list

class DeviceGetAll(DetailView):
    if Host.objects.values():
        create_devices()
        model = Device
    pass
 

Ответ №1:

Ваше мнение DeviceGetAll написано неправильно. if Условие должно быть помещено в некоторые методы представления, а не в определение класса.

Я не понимаю, что именно вы пытаетесь сделать, поэтому я не могу знать, в какой метод вам нужно добавить код, но вы можете посмотреть базовый код DetailView и посмотреть, полезны ли вам некоторые из этих методов. Я даже не знаю, является ли подробное представление лучшим местом для размещения кода, который создает экземпляры одной и той же модели; возможно, он также может быть создан после создания хоста.


Но если вы хотите использовать DetailView , вы могли бы, например, переопределить метод get_object() из SingleObjectMixin (который является одним из родителей DetailView ), ваш код может выглядеть следующим образом:

 class DeviceGetAll(DetailView):
    model = Device

    def get_object(self, *args, **kwargs):
        if Host.objects.exists():
            create_devices()

        obj = super().get_object(*args, **kwargs)
        return obj
 

Кроме того, вы, вероятно, хотите использовать .exists() метод в условии if вместо .values() .

Комментарии:

1. Танков много! позор мне, существует () — это то, что мне было нужно. Итак, можно сканировать сеть внутри представления, вводить ее в базу данных и создавать подробное представление всех устройств одного класса? или есть более удобный способ?

2. @kadopsdong Если вам нужно, чтобы решения создавались, как только появится один хост, я предлагаю добавить этот код в CreateView.form_valid() Host модель.

3. Идеально:) но нет никакого способа сканировать сеть как nyc, верно? Единственная возможность — это использовать пул потоков, чтобы сделать это быстро.

4. @kadopsdong Если вам нужна асинхронность, вы можете изучить Сельдерей или джанго-фоновые задачи

5. Здравствуйте, к сожалению, это та же проблема после удаления базы данных… когда я использую exists, она выдает ошибку, потому что нет настройки хоста.