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

Django更新Member记录时重复创建新条目,求解决方案

问题:Django更新Member记录时总是创建新条目而非更新现有记录

我是Python和Django新手,开发的应用可创建、更新SQL数据库中的自定义Member表。创建功能正常,但执行更新操作时,每次提交都会生成新记录,无法更新现有Member条目。

视图逻辑:VIEW.py通过URL参数?id=记录ID和&ed=T显示编辑表单,相关代码如下:

# LISTS VIEWS
class NewMember(LoginRequiredMixin,TemplateView):

    def get(self, request, *args, **kwargs):
        memberId = request.GET.get('id')
        isEdit = request.GET.get('ed')
        print('NEW MEMBER VIEW TRIGGERED')
        print(memberId)
        print(isEdit)
        if isEdit == 'T':
            memberObject = Member.objects.get(id=memberId)
            form = MemberForm(instance=memberObject)  
            print("EDIT TRIGGERED")
            return render(request, 'components/list/list-new-member.html', {'form':form, 'memberid':memberId})
        elif memberId:
            form = MemberForm()
            context = Member.objects.get(id=memberId)
            print('VIEW MEMBER TRIGGERED')
            return render(request, 'components/list/list-view-member.html', {'context':context,'form':form})
        else:
            # CREATE NEW MEMBER
            form = MemberForm()
            context = {'form':form}
            return render(request, 'components/list/list-new-member.html', context)

    def post(self, request, *args, **kwargs):
        print('REST POST PRINTED')
        form = MemberForm(request.POST, request.FILES)
        if form.is_valid():
            retObj = form.save()
            print('RECORD UPDATED')
            return redirect('/app/list/member?id='+str(retObj.id))

        else:
            print(request.POST)
            print(form.errors)
            print('REST PRINTING POST :form.is_valid() '+ str(form.is_valid()))
            if form.is_valid():
                retObj = form.save()
                print(retObj.id)
                return redirect('/app/list/member?id='+str(retObj.id))

        context = {'form':form}
        return render(request, 'components/list/list-new-member.html', context)

Member模型代码(Model.py)

# MEMBER MODEL
class Member(models.Model):
    TYPE = (
        (1, 'Associate'),
        (2, 'Supervisor'),
        (3, 'Region Head'),
        (4, 'Country Head')
    )

    GENDER = (
        (1, 'Female'),
        (2, 'Male'),
        (3, 'Other')
    )

    QUALIFICATION = (
        (1, 'Under Graduate'),
        (2, 'Graduate'),
        (3, 'Masters'),
        (4, 'PhD')
    )

    MEMBERSTATUS = (
        (1, 'Lead'),
        (2, 'Pending Approval'),
        (3, 'Active'),
        (4, 'Rejected'),
        (5, 'Terminated')
    )

    firstname = models.CharField(max_length = 120)
    middlename = models.CharField(max_length = 50, null=True)
    lastname = models.CharField(max_length = 100)
    registrationuniquekey = models.CharField(max_length = 30, null=True)
    
    profession = models.CharField(max_length = 100, null=True)    
    birthdate = models.DateField(auto_now=False, auto_now_add=False, null=True)
    gender = models.IntegerField(choices=GENDER, null=True)

    aadhaar = models.CharField(max_length = 12, null=True)
    aadhaarfile = models.ImageField(upload_to='memberfile/' , null=True, blank=True)
    profilephoto = models.ImageField(upload_to='memberfile/' , null=True, blank=True)

    memberid = models.CharField(max_length=30, null=True)
    memberstatus = models.IntegerField(choices=MEMBERSTATUS, null=True)
    registrationlink = models.CharField(max_length = 200, null=True)
    
    email = models.EmailField(max_length = 100)
    phone = models.CharField(max_length = 12, null=True)
    country = models.ForeignKey(Country, null=True, on_delete=models.SET_NULL)

    address = models.TextField(max_length = 999 , null=True)

    qualification = models.IntegerField(choices=QUALIFICATION, null=True)
    hobbies = models.CharField(max_length = 100, null=True)
    extraactivities = models.CharField(max_length = 200, null=True)

    lifegoals = models.TextField(max_length = 400, null=True)
    whywe = models.TextField(max_length = 400, null=True)
    notes = models.TextField(max_length = 400, null=True)

    referredby = models.CharField(max_length = 100,default=1)
    requestedby = models.ForeignKey(User, on_delete=models.CASCADE, default=2)
    type = models.IntegerField(choices=TYPE, null=True)
    
    approvedbystate = models.CharField(max_length = 100, null=True)
    approvedbypresident = models.CharField(max_length = 100, null=True)
    datecreated = models.DateTimeField(auto_now_add=True)
    iagree = models.BooleanField(null=True)

    def save(self, *args, **kwargs):
        if not self.registrationlink:
            self.registrationlink = None
        super(Member, self).save(*args, **kwargs)

    def __str__(self):
        return self.firstname

Member表单代码(FORM.py)

class MemberForm(forms.ModelForm):
    class Meta:
        model = Member
        fields = (
        'firstname', 
        'middlename', 
        'lastname', 
        'profession', 
        'gender',
        'aadhaar',
        'aadhaarfile',
        'profilephoto',
        'birthdate',
        'email',
        'phone',
        'country',
        'address',
        'qualification',
        'hobbies',
        'extraactivities',
        'lifegoals',
        'whywe',
        'referredby',
        'type',
        'approvedbystate',
        'approvedbypresident',
        'iagree',
        'requestedby')

        widgets = {
        'firstname':    forms.TextInput(attrs={'class':'form-control'}),
        'middlename':   forms.TextInput(attrs={'class':'form-control'}), 
        'lastname':     forms.TextInput(attrs={'class':'form-control'}),
        'profession':   forms.TextInput(attrs={'class':'form-control'}),
        'birthdate':    forms.DateInput(attrs={'class':'form-control', 'type':'date'}),
        'gender':       forms.Select(attrs={'class':'form-control'}),
        'aadhaar':      forms.NumberInput(attrs={'class':'form-control'}), 
        'aadhaarfile':  forms.FileInput(attrs={'class':'form-control'}), 
        'profilephoto': forms.FileInput(attrs={'class':'form-control'}), 
        'email':        forms.EmailInput(attrs={'class':'form-control'}),
        'phone':        forms.NumberInput(attrs={'class':'form-control', 'type':'tel'}),
        'country':      forms.Select(attrs={'class':'form-control'}),
        'address':      forms.Textarea(attrs={'class':'form-control'}),
        'qualification':forms.Select(attrs={'class':'form-control'}),   
        'hobbies':      forms.TextInput(attrs={'class':'form-control'}),
        'extraactivities': forms.TextInput(attrs={'class':'form-control'}),
        'lifegoals':    forms.Textarea(attrs={'class':'form-control'}),
        'whywe':        forms.Textarea(attrs={'class':'form-control'}),
        'referredby':   forms.TextInput(attrs={'class':'form-control'}),
        'type':         forms.Select(attrs={'class':'form-control'}),
        'approvedbystate':forms.TextInput(attrs={'class':'form-control'}),
        'approvedbypresident':forms.TextInput(attrs={'class':'form-control'}),
        'requestedby':  forms.Select(attrs={'class':'form-control'}),
        'iagree':forms.CheckboxInput()
        }
解决方案

核心问题是POST方法未传入要更新的instance对象。GET请求中正确加载了带instance的表单,但POST提交时,创建的是全新的MemberForm(request.POST, request.FILES),未关联目标Member实例,导致Django默认创建新记录。

修改后的POST方法代码:

def post(self, request, *args, **kwargs):
    print('REST POST PRINTED')
    memberId = request.GET.get('id')
    isEdit = request.GET.get('ed')
    
    # 根据编辑状态初始化表单
    if isEdit == 'T' and memberId:
        member_object = Member.objects.get(id=memberId)
        form = MemberForm(request.POST, request.FILES, instance=member_object)
    else:
        form = MemberForm(request.POST, request.FILES)
    
    if form.is_valid():
        retObj = form.save()
        print('RECORD SAVED')
        return redirect(f'/app/list/member?id={retObj.id}')
    else:
        print(request.POST)
        print(form.errors)
        print(f'FORM VALIDITY: {form.is_valid()}')
        return render(request, 'components/list/list-new-member.html', {'form':form})

额外优化建议

  • 避免依赖GET参数传递ID,推荐在编辑页面的表单中添加隐藏字段:
    <input type="hidden" name="member_id" value="{{ memberid }}">
    
    之后在POST方法中通过request.POST.get('member_id')获取ID,更安全可靠。
  • 使用Django内置的通用视图(如UpdateView、CreateView),可大幅减少重复代码,符合Django最佳实践。

内容的提问来源于stack exchange,提问作者Faizan Siddiki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 19:00:53