You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 11:33:10