В настоящее время я делаю приложение для управления брандмауэром для Django, вот (упрощенная) модель:
class Port(models.Model):
number = models.PositiveIntegerField(primary_key=True)
application = models.CharField(max_length=16, blank=True)
class Rule(models.Model):
port = models.ForeignKey(Port)
ip_source = models.IPAddressField()
ip_mask = models.IntegerField(validators=[MaxValueValidator(32)])
machine = models.ForeignKey("vmm.machine")
Однако я хотел бы показать пользователю форму для ввода правил, но с совсем другой организацией, нежели модель:
Порт 80
O Не открыто
O Везде
O Конкретные адреса:
--------- удалить поле
--------- удалить поле
+
добавить поле адреса
Порт 443
... и т. Д.
Где Not open
означает, что для данного порта нет никаких правил, Everywhere
означает, что для данного порта существует только ОДНО правило (0.0.0.0/0), а с помощью specific addresses
вы можете добавить как столько адресов, сколько вы хотите (я сделал это с помощью JQuery), что позволит создать столько правил.
Теперь я сделал версию полностью «ручной», что означает, что я создаю формы полностью в своих шаблонах, задаю имена входов с префиксом и анализирую все POST-элементы в моем представлении (что довольно болезненно и означает, что нет смысла использовать веб-фреймворк).
У меня также есть класс, который объединяет правила вместе, чтобы легко предварительно заполнить формы информацией "не открыто, везде ...". Я передаю их список шаблону, поэтому он действует как интерфейс между моей моделью и моей формой "ручной работы":
class MachinePort(object):
def __init__(self, machine, port):
self.machine = machine
self.port = port
@property
def fully_open(self):
for rule in self.port.rule_set.filter(machine=self.machine):
if ipaddr.IPv4Network("%s/%s" % (rule.ip_source, rule.ip_mask)) == ipaddr.IPv4Network("0.0.0.0/0"):
return True
else :
return False
@property
def partly_open(self):
return bool(self.port.rule_set.filter(machine=self.machine)) and not self.fully_open
@property
def not_open(self):
return not self.partly_open and not self.fully_open
Но все это довольно безобразно! Кто-нибудь из вас знает, есть ли классный способ сделать это? В частности, с формой ... Я не знаю, как иметь форму, которая может иметь неопределенное количество полей, а также как преобразовать эти поля в Rule
объекты (потому что все поля правила должны быть собраны из форма), ни как сохранить несколько объектов ... Ну, я мог бы попытаться взломать класс Form, но, похоже, слишком много работы для такого особого случая. Есть ли какая-нибудь приятная особенность, которую мне не хватает?