使用Django inlineformset_factory编辑子记录时触发ORA-00001唯一约束(SDESERP.UK_CODELKUP)违反错误的求助
Django inlineformset_factory编辑子记录时触发ORA-00001唯一约束(SDESERP.UK_CODELKUP)违反错误的求助
大家好,我最近在Django里用inlineformset_factory实现父子模型的表单功能,但是编辑子记录的时候总是碰到ORA-00001唯一约束违反的错误,已经卡了两天了,实在找不到问题出在哪。下面是我的模型、表单和视图代码,麻烦各位帮忙看看怎么解决!
模型代码
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}"
表单代码
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) super().__init__(*args, **kwargs) # 编辑时锁定code字段,避免用户修改 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', {}) self.request = form_kwargs.get('request', None) self.is_edit = form_kwargs.get('is_edit', False) kwargs['form_kwargs'] ={'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 )
视图代码
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.save() messages.success(request, "数据更新成功!") return redirect('system_codes_list') except IntegrityError as e: messages.error(request, f"错误:{str(e)}") else: messages.error(request, "表单数据无效,请检查输入。") else: form = CodeListForm(instance=codelist, is_edit=is_edit, request=request) formset = CodeLkupFormSet(instance=codelist, form_kwargs={'request': request, 'is_edit': is_edit}) context = { 'form': form, 'formset': formset, 'is_edit': is_edit } return render(request, 'system_codes/edit.html', context)
我已经把编辑时的code字段设为只读了,避免用户修改,但还是触发了唯一约束。看错误提示是SDESERP.UK_CODELKUP,这个应该就是listname和code的联合唯一约束,但编辑的时候这两个值都没改啊,实在搞不懂为什么会冲突。
内容来源于stack exchange
相关产品推荐
相关产品推荐

