ORA-00001: unique constraint (SDESERP.UK_CODELKUP) violated, django inlineformset
Hi I am trying to create a form with parent-child models using python Django Inlineformset_factory but when I am trying to update the child, its giving me unique constraint error. Here I am sharing my model code, forms code, views code. I am trying to solve this issue since last two days but not succeeded. please help me to solve the issue.
Models code-->
class CodeList(models.Model):
listname = models.CharField(db_column='LISTNAME', max_length=20, primary_key=True)
description = models.CharField(db_column='DESCRIPTION', max_length=100)
adddate = models.DateField(db_column='ADDDATE')
addwho = models.CharField(db_column='ADDWHO', max_length=20)
editdate = models.DateField(db_column='EDITDATE')
editwho = models.CharField(db_column='EDITWHO', max_length=20)
class Meta:
db_table ='CODELIST'
def __str__(self):
return f"{self.listname}"
class CodeLkup(models.Model):
listname = models.ForeignKey(CodeList, db_column='LISTNAME', on_delete=models.CASCADE)
code = models.CharField(db_column='CODE', max_length=30, primary_key=True) #,
eng_desc = models.CharField(db_column='ENG_DESC', max_length=250)
bl_desc = models.CharField(db_column='BL_DESC', max_length=250, blank=True)
adddate = models.DateField(db_column='ADDDATE')
addwho = models.CharField(db_column='ADDWHO', max_length=20)
editdate = models.DateField(db_column='EDITDATE')
editwho = models.CharField(db_column='EDITWHO', max_length=20)
class Meta:
db_table = 'CODELKUP'
unique_together = ('listname', 'code')
def __str__(self):
return f"{self.code}-{self.eng_desc}"
forms code-->
class CodeListForm(forms.ModelForm):
class Meta:
model = CodeList
fields = ['listname','description']
widgets ={
'listname' : forms.TextInput(attrs={'class' : 'form-control form-control-sm', 'autocomplete' : 'off'}),
'description' : forms.TextInput(attrs= {'class' : 'form-control form-control-sm' , 'autocomplete' : 'off'})
}
def __init__(self, *args, **kwargs):
is_edit = kwargs.pop('is_edit', False)
self.request = kwargs.pop('request', None)
super(CodeListForm, self).__init__(*args, **kwargs)
if is_edit:
self.fields['listname'].widget.attrs['readonly']=True
def save(self, commit=True):
codelist = super().save(commit=False)
userid = self.request.session.get("UserId")
if self.instance.pk and CodeList.objects.filter(pk=self.instance.pk).exists():
codelist.editdate = timezone.now()
codelist.editwho = userid
else:
codelist.adddate = timezone.now()
codelist.addwho = userid
codelist.editdate = timezone.now()
codelist.editwho = userid
if commit:
codelist.save()
return codelist
class CodeLkupForm(forms.ModelForm):
class Meta:
model = CodeLkup
exclude = ['listname']
fields = ['code', 'eng_desc', 'bl_desc']
widgets = {
'code': forms.TextInput(attrs={'class': 'form-control form-control-sm', 'autocomplete': 'off'}),
'eng_desc': forms.TextInput(attrs={'class': 'form-control form-control-sm', 'autocomplete': 'off'}),
'bl_desc': forms.TextInput(attrs={'class': 'form-control form-control-sm', 'autocomplete': 'off', 'dir': 'rtl'}),
}
def __init__(self, *args, **kwargs):
self.is_edit = kwargs.pop('is_edit', False)
self.request = kwargs.pop('request', None)
#self.parent_instance = kwargs.pop('parent_instance', None)
super().__init__(*args, **kwargs)
# Only disable code field if this is an existing object
if self.is_edit:
self.fields['code'].widget.attrs['readonly']=True
def save(self, commit=True):
codelkup = super().save(commit=False)
userid = self.request.session.get("UserId") if self.request and hasattr(self.request, 'session') else None
if self.instance.pk:
print("a")
codelkup.instance = self.instance
codelkup.editdate = timezone.now()
codelkup.editwho = userid
else:
print("b")
codelkup.adddate = timezone.now()
codelkup.addwho = userid
codelkup.editdate = timezone.now()
codelkup.editwho = userid
if commit:
codelkup.save()
return codelkup
class CustomCodeLkupFormSet(BaseInlineFormSet):
def __init__(self, *args, **kwargs):
#form_kwargs = kwargs.pop('form_kwargs', {})
form_kwargs = kwargs.pop('form_kwargs', {})
self.request = form_kwargs.get('request', None)
self.is_edit = form_kwargs.get('is_edit', False)
#kwargs['form_kwargs'] = kwargs.pop('form_kwargs', {})
kwargs['form_kwargs'] ={'request': self.request, 'is_edit': self.is_edit}
#kwargs['form_kwargs'].update({'request': self.request, 'is_edit': self.is_edit})
super().__init__(*args, **kwargs)
CodeLkupFormSet = inlineformset_factory(
CodeList,
CodeLkup,
form=CodeLkupForm,
formset=CustomCodeLkupFormSet,
extra=1,
can_delete=True
)
views code-->
def edit_system_codes(request, listname):
is_edit = True
codelist = get_object_or_404(CodeList, listname=listname)
instance = codelist
codelkup =CodeLkup.objects.filter(listname=listname)
if request.method == 'POST':
form = CodeListForm(request.POST or None, request=request, instance=codelist, is_edit=is_edit)
formset = CodeLkupFormSet(request.POST or None, instance=codelist, form_kwargs={
'request': request,
'is_edit': True})
if form.is_valid() and formset.is_valid():
try:
master = form.save()
formset.instance = master
formset.save()
messages.success(request, _("LBL_SAVED"))
return redirect('codes_list')
except IntegrityError as e:
error_msg = str(e)
print(error_msg)
messages.error(request, f'{{ error_msg }}')
except DatabaseError as e:
messages.error(request, f'Database error occured: {str(e)}')
except Exception as e:
messages.error(request, f'unexpected error: {str(e)}')
else:
form = CodeListForm(request=request, is_edit=is_edit, instance=codelist)
formset = CodeLkupFormSet(instance=codelist, form_kwargs={
'request': request,
'is_edit': True})
return render(request, 'system_codes/edit_system_codes.html', {'form' : form, 'formset' : formset})
html code-->
<div class="row p-1 pt-0"><!--justify-content-center-->
<div class="col-md-10">
<div class="card bg-light">
<div class="card-header p-1">
<i class="fa-solid fa-plus fa-lg"></i> {% trans "LBL_EDIT_CODES" %}
</div>
<form action="" method="POST" id="edit_system_codes_form">
{% csrf_token %}
<div class="card-body p-1">
<!--{{ form.as_p }}-->
<div class="row mb-2">
<div class="col-md-4">
<label class="form-label">{% trans "LBL_LISTNAME" %}<span Class="text-danger">*</span></label>
{{ form.listname }}
</div>
</div>
<div class="row mb-2">
<div class="col-md-10">
<label class="form-label">{% trans "LBL_DESCRIPTION" %}<span Class="text-danger">*</span></label>
{{ form.description }}
</div>
</div>
{{ formset.management_form }}
<div class="row">
<div class="col-md-12 text-center">
<h4>{% trans "LBL_CODELKUP_DETAIL" %}</h4>
</div>
</div>
<div class="row">
<div class="col-md-12">
<table class="table table-bordered custom-table">
<thead class="table-light">
<tr>
<th class="align-middle">{% trans "LBL_CODE" %}</th>
<th class="align-middle">{% trans "LBL_DESCRIPTION" %}</th>
<th class="align-middle">{% trans "LBL_BL_DESCRIPTION" %}</th>
<th>
<button type="button" class="btn btn-sm btn-success"
title="{% trans 'LBL_ADD' %}">
<i class="fa-solid fa-plus"></i>
</button>
</th>
</tr>
</thead>
<tbody>
{% for f in formset %}
<tr>
<td style="width:20%">{{ f.code }}</td>
<td style="width:40%">{{ f.eng_desc }}</td>
<td style="width:40%">{{ f.bl_desc }}</td>
<td>
<button type="button" class="btn btn-sm btn-danger"
title="{% trans 'LBL_DELETE_BUTTON' %}">
<i class="fa-solid fa-trash"></i>
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<div class="card-footer text-end pb-0">
<button type="button" id="edit_system_codes_save_button" class="btn btn-success">{% trans "LBL_SAVE_BUTTON" %}</button>
<a href="{% url 'codes_list' %}" class="btn btn-secondary">{% trans "LBL_CANCEL_BUTTON" %}</a>
</div>
</form>
</div>
</div>
</div>
{% include 'loader.html' %}
javascript code-->
<script>
$(document).ready(function(){
hideLoader();
$('#edit_system_codes_save_button').click(function(){
showLoader();
document.getElementById('edit_system_codes_form').submit();
})
});
</script>