di_form is not doing is_valid() properly

models.py

class DeviceInterface(models.Model):
    MODULE_ID_CHOICES = (
        ('TenGigabitEthernet','TenGigabitEthernet'), 
        ('FortyGigabitEthernet','FortyGigabitEthernet'),
        ('GigabitEthernet','GigabitEthernet'),
        ('Ethernet','Ethernet'),        
    )
    
    moduletype = models.CharField(max_length = 50,choices = MODULE_ID_CHOICES)
    firstportid = models.CharField(max_length=50)
    lastportid = models.CharField(max_length=50)
    I2DKEY = models.ForeignKey(Device, on_delete=models.CASCADE) ##The key to link up the tables

    def __str__(self):
        return self.moduletype

forms.py

class DeviceInterfaceForm(ModelForm):
    class Meta:
        model= DeviceInterface
        fields= ['moduletype', 'firstportid', 'lastportid']
        labels = {
            "moduletype":"Module Type",
            "firstportid": "First Port ID",
            "lastportid": "Last Port ID"
        }

Part of views.py

                    if di_form.is_valid():
                       deviceI=di_form.save(commit=False) 
                       print(deviceI)
                       for instances in deviceI:          
                         instances.I2DKEY=new_device
                         instances.save()
                       return render(request, 'interface/device_added.html',{'devices':Device.objects.all()})
                    else:
                        print(deviceI.errors)

I have the following codes above, few weeks ago it is working. But now its not working. When i submit my form, it somehow goes is_valid()=True. So meaning my text fields for this model can be empty and the form can still be saved somehow. PS: This webpage have a total of 3 different forms. So if this form’s field are all empty, it saves the the other models instead.

Can anyone explain to me what am i doing wrongly?

We don’t have a clear picture of what you’re trying and what you expect to happen. Can you please post your full view? Also, please try to get the indentation as it exists in your files. It’s important for python and if there’s a problem there it’s hard for us to tell. For example the print() line in the else has a different indentation than the other branch.

Regarding is_valid() resolving to True, why do you think that is? Asked another way, what are you doing that makes you expect it to resolve to False?

Heres the full view:

 def device_add(request):
    if request.method == "POST":
        device_frm = DeviceForm(request.POST) 
        dd_form = DeviceDetailForm(request.POST)
        
        di_formset = inlineformset_factory(Device, DeviceInterface, fields=('moduletype', 'firstportid', 'lastportid'),widgets={  'firstportid':TextInput(attrs={'placeholder': 'e.g. TenGigabitEthernet1/0/1'}), 'lastportid':TextInput(attrs={'placeholder':'eg. TenGigabitEthernet1/0/48'})},extra=1,max_num=3, can_delete=False)
        di_form=di_formset(request.POST)
        if device_frm.is_valid():
        # Create and save the device
        # new_device here is the newly created Device object
            new_device = device_frm.save()
            if dd_form.is_valid():
                # Create an unsaved instance of device detail
                deviceD = dd_form.save(commit=False)
                # Set the device we just created above as this device detail's device
                deviceD.DD2DKEY = new_device              
                deviceD.save()
                if di_form.is_valid():
                    deviceI=di_form.save(commit=False) 
                    print(deviceI)
                    for instances in deviceI:          
                        instances.I2DKEY=new_device
                        instances.save()
                    return render(request, 'interface/device_added.html',{'devices':Device.objects.all()})
                return render(request,'interface/device_add.html',{'form':device_frm, 'dd_form': dd_form, 'di_form':di_form})
            return render(request,'interface/device_add.html',{'form':device_frm, 'dd_form': dd_form, 'di_form':di_form})
        return render(request,'interface/device_add.html',{'form':device_frm, 'dd_form': dd_form, 'di_form':di_form})
    else:
        device_frm = DeviceForm()
        dd_form = DeviceDetailForm()
        di_formset = inlineformset_factory(Device, DeviceInterface, fields=('moduletype', 'firstportid', 'lastportid'), widgets={  'firstportid':TextInput(attrs={'placeholder': 'e.g. TenGigabitEthernet1/0/1'}), 'lastportid':TextInput(attrs={'placeholder':'eg. TenGigabitEthernet1/0/48'})},extra=1, max_num=3, can_delete=False)
        di_form=di_formset(queryset = DeviceInterface.objects.none())
        return render(request,'interface/device_add.html',{'form':device_frm, 'dd_form': dd_form, 'di_form':di_form})

Answering your question, I have no idea. I have not been editing my views so far as I am currently trying to resolve my issue in the html to control my formset properly which I am not able to do it yet. So i dont know how it is resolving to true everytime.

If the issue is that is_valid() is returning True unexpectedly, I’d check to see what the POST is submitting via a browser’s developer tools’ network panel, then comparing that to what the forms expect and the validations implied in them.

I checked it in powershell instead and apparently its taking [ ] for deviceI