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,推荐在编辑页面的表单中添加隐藏字段:
之后在POST方法中通过<input type="hidden" name="member_id" value="{{ memberid }}">request.POST.get('member_id')获取ID,更安全可靠。 - 使用Django内置的通用视图(如
UpdateView、CreateView),可大幅减少重复代码,符合Django最佳实践。
内容的提问来源于stack exchange,提问作者Faizan Siddiki
相关产品推荐
相关产品推荐

