Reputation: 97
I'm having a trouble where I want to use a form to update 2 different tables. My current form have a few variables. Hostname, ipaddr, mgmt, mgmtip etc. What I want to do now is take hostname, ipaddr and add into one table (This one done) and the other 2, mgmt and mgmtip to another table while under the same id. Like for example, hostname and ipaddr is registered under id of 1 (1st row of table 1) and mgmt and mgmtip to table 2 of the same id = 1. I am currently also able to extract the id for the 1st table. But I just cant seem to update the table2 under the same id.
Below is my code: In views.py
def device_add(request):
if request.method == "POST":
device_frm = DeviceForm(request.POST) ##Part A1
dd_frm = DeviceDetailForm()
if device_frm.is_valid():
device_frm.save() ##Part A1
deviceid = Device.objects.aggregate(Max('id')) ##Part A1 - Getting the ID of added device
device = Device.objects.all() ##Part A1
if dd_frm.is_valid():
dd_frm.save('id' == deviceid)
return render(request, 'interface/device-added.html',{'devices':device})
else:
device_frm = DeviceForm()
dd_frm = DeviceDetailForm()
di_frm = DeviceInterfaceForm()
return render(request,'interface/device_add.html',{'form':device_frm, 'dd_form': dd_frm})
In models.py
class DeviceDetail(models.Model):
hostname = models.CharField(max_length=50)
mgt_interface = models.CharField(max_length=50)
mgt_ip_addr = models.CharField(max_length=30)
subnetmask = models.CharField(max_length=30)
ssh_id = models.CharField(max_length=50)
ssh_pwd = models.CharField(max_length=50)
enable_secret = models.CharField(max_length=50)
device_model = models.CharField(max_length=50)
def __str__(self):
return self.hostname
In forms.py
class DeviceDetailForm(ModelForm):
class Meta:
model= DeviceDetail
fields= ['hostname', 'mgt_interface', 'mgt_ip_addr', 'subnetmask', 'ssh_id', 'ssh_pwd', 'enable_secret', 'device_model']
def clean(self):
cleaned_data = super(DeviceDetailForm, self).clean()
hostname = cleaned_data.get('hostname')
if len(hostname) < 8:
raise forms.ValidationError('Hostname needs to be more than 8 character long, ' + hostname )
Upvotes: 1
Views: 77
Reputation: 69
if you want to relative two tables together you must use relative fields in your model, like ForeignKey, ManyToManyField, and ...,
model:
class DeviceModel(Model.models):
hostname = models.CharField(max_length=100)
ipaddr = models.CharField(max_length=50)
class DeviceDetailModel(Model.models):
device = models.ForeignKey(DeviceModel, related_name='Device_Model', on_delete=models.CASCADE)
mgmt = models.SOMEField
mgmtip = models.SOMEField
Form:
from django import forms
from .models import DeviceModel, DeviceDetailModel
class DeviceForm(forms.ModelForm):
class Meta:
model = DeviceModel
fields = '__all__'
class DeviceDetailForm(forms.ModelForm):
mgmt = forms.SOMEField
mgmtip = forms.SOMEField
class Meta:
model = DeviceDetailModel
fields = '__all__'
and now
if request.method == "POST":
device_frm = DeviceForm(request.POST)
dd_frm = DeviceDetailForm(request.POST)
if device_frm.is_valid():
device_frm.save() ##Part A1
deviceid = Device.objects.aggregate(Max('id'))
device = Device.objects.all() ##Part A1
if dd_frm.is_valid():
deviceD = dd_frm.save(commit=False)
deviceD.device = Device.objects.get(id=deviceid)
deviceD.save()
return render(request, 'interface/device-added.html',{'devices':device})
P.S: you forget to add request.POST
to dd_frm = DeviceDetailForm(request.POST)
Upvotes: 1
Reputation: 476594
Your model should work with a ForeignKey
or OneToOneField
to refer to the device it is linked to, so:
class DeviceDetail(models.Model):
# …
device_model = models.ForeignKey(Device, on_delete=models.CASCADE)
In your form, you should return the cleaned data after validation, so:
class DeviceDetailForm(ModelForm):
class Meta:
model= DeviceDetail
fields= ['hostname', 'mgt_interface', 'mgt_ip_addr', 'subnetmask', 'ssh_id', 'ssh_pwd', 'enable_secret', 'device_model']
def clean(self):
cleaned_data = super().clean()
hostname = cleaned_data.get('hostname')
if len(hostname) < 8:
raise forms.ValidationError(f'Hostname needs to be more than 8 character long, {hostname}')
return cleaned_data
or cleaner:
class DeviceDetailForm(ModelForm):
class Meta:
model= DeviceDetail
fields= ['hostname', 'mgt_interface', 'mgt_ip_addr', 'subnetmask', 'ssh_id', 'ssh_pwd', 'enable_secret', 'device_model']
def clean_hostname(self):
hostname = self.cleaned_data['hostname']
if len(hostname) < 8:
raise forms.ValidationError(f'Hostname needs to be more than 8 character long, {hostname}')
return hostname
You can set the .device_model_id
with the primary key of the altered device with:
if request.method == 'POST':
device_frm = DeviceForm(request.POST)
dd_frm = DeviceDetailForm(request.POST)
if device_frm.is_valid() and dd_from.is_valid():
device = device_frm.save()
if dd_frm.is_valid():
dd_frm.instance.device_model = device
dd_frm.save()
# …
Note: In case of a successful POST request, you should make a
redirect
[Django-doc] to implement the Post/Redirect/Get pattern [wiki]. This avoids that you make the same POST request when the user refreshes the browser.
Upvotes: 0