Как связать существующего ребенка с родителем в Django
Я пытаюсь построить IPAM на Django. Я буду создавать модель подсети и создавать IPA-адрес по сигналу post_save.
class Subnet(models.Model):
usage = models.CharField('Usage', max_length=40)
vlan = models.PositiveSmallIntegerField('vlan')
cidr = models.CharField('CIDR', max_length=18)
gateway = models.GenericIPAddressField('Gateway')
def __str__(self):
return str(self.vlan) + ' ' + self.usage
class IPAddress(models.Model):
subnet = models.ForeignKey(Subnet, on_delete=models.CASCADE, verbose_name="Subnet")
ip = models.GenericIPAddressField('IP Address', unique=True)
mac = models.CharField('Mac Address', max_length=17, blank=True, null=True)
vm = models.ForeignKey(VM, on_delete=models.SET_NULL, blank=True, null=True)
class Meta:
indexes = [
models.Index(fields=['ip','mac']),
models.Index(fields=['ip'], name='vm_ip_idx'),
]
verbose_name = 'IP Address'
verbose_name_plural = 'IP Addresses'
def __str__(self):
return str(self.ip)
@receiver(post_save, sender=Subnet)
def create_ip(sender, instance, created, **kwargs):
if created:
except_ip = ["0","255"]
for ip in ipaddress.IPv4Network(instance.cidr):
if (str(ip) != str(instance.gateway)) and (str(ip).split('.')[-1] not in [i for i in except_ip]):
IPAddress(subnet=instance, ip=str(ip)).save()
class VM(models.Model):
vm_name = models.CharField('VM Name', max_length=60)
def __str__(self):
return str(self.vm_name)
Что я хочу сделать: Я создал подсеть с CIDR 172.0.0.0/24 и автоматически создал 255 IPAddress (172.0.0.1-172.0.0.254). И теперь я хочу прикрепить один из IPAddress к виртуальной машине и обновить MAC-адрес на странице администратора.
Я пытался редактировать в файле admin.py
class VMIPAdminForm(forms.ModelForm):
ip = forms.ModelChoiceField(queryset=IPAddress.objects.all(), empty_label="IP Address")
mac = forms.CharField(max_length=17, required=False, label="MAC Address")
class Meta:
model = IPAddress
fields = ['ip', 'mac']
class VMIPInline(admin.TabularInline):
model = IPAddress
form = VMIPAdminForm
exclude = ['subnet']
extra = 1
fk_name = "vm"
@admin.register(VM)
class VMAdmin(admin.ModelAdmin):
inlines = [VMIPInline]
Но он покажет, что IP-адрес с таким IP-адресом уже существует, когда я выберу IP-адрес и введу MAC-адрес в VM.