#python #django #django-models #django-views
Вопрос:
Я хочу хранить данные сетевых устройств с помощью модели Django Device
в своей базе данных.
Рабочий процесс
- Конфигурация хоста должна быть настроена пользователем внутри представления (модели хоста).
- Когда конфигурация хоста завершена, сеть должна быть проверена на наличие устройств (модель устройства).
- Данные должны храниться внутри базы данных
Проблема:
Функция create_devices()
может вызываться только тогда, когда хост настроен, но if Host.objects.values():
не работает.
- Как можно вызвать функцию
create_devices()
только в том случае, если существует одна модель хоста? - Правильно ли использовать представление для хранения динамических и статических данных в базе данных без взаимодействия с пользователем?
Модели:
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, она выдает ошибку, потому что нет настройки хоста.