My edit view in my application won't update the court details whenever I want to edit it. I keep getting the error below. Adding, Viewing & Deleting functions are working okay. I cant find a solution on the other S/O answers. Some help on this would be appreciated. Thanks
Exception Value: 'str' object has no attribute 'court_number'
model.py
# Create your models here.
class Court(models.Model):
court_number = models.CharField(max_length=255, verbose_name='Court Number.')
accused_person = models.ForeignKey(AccusedPerson, on_delete=models.CASCADE, verbose_name='Accused Person')
court = models.CharField(choices=COURTS, max_length=255, verbose_name='Court')
court_verdict = models.CharField(choices=VERDICT, max_length=50, verbose_name='Court Status')
scheduled_on = models.DateField(verbose_name='Scheduled On')
created_by = models.ForeignKey(Profile, on_delete=models.CASCADE, verbose_name='Police Officer')
date_created = models.DateTimeField(auto_now_add=True, verbose_name='Date Created')
date_updated = models.DateTimeField(auto_now=True, verbose_name='Date Updated')
def __str__(self):
return str(self.court_number)
class Meta:
verbose_name_plural = 'Court'
forms.py
class EditCourtInfoForm(forms.Form):
court_number = forms.CharField(max_length=50, required=True, widget=forms.TextInput(attrs={'id': 'court_number', 'class': 'form-control mb-4', 'name': 'court_number', 'placeholder': 'Court Number'}))
accused_person = forms.ChoiceField(required=True, widget=forms.Select(attrs={'id': 'accused_person', 'class': 'form-control mb-4', 'name': 'accused_person', 'placeholder': 'Accused Person'}))
court = forms.ChoiceField(choices=COURTS, required=True, widget=forms.Select(attrs={'id': 'court', 'class': 'form-control mb-4', 'name': 'court', 'placeholder': 'Court'}))
court_verdict = forms.ChoiceField(choices=VERDICT, required=True, widget=forms.Select(attrs={'id': 'court_verdict', 'class': 'form-control mb-4', 'name': 'court_verdict', 'placeholder': 'Verdict'}))
scheduled_on = forms.DateField(required=True, widget=forms.DateInput(attrs={'type': 'date', 'id': 'scheduled_on', 'class': 'form-control mb-4', 'name': 'scheduled_on', 'placeholder': 'Scheduled On'}))
def __init__(self, *args, **kwargs):
super(EditCourtInfoForm, self).__init__(*args, **kwargs)
self.fields['accused_person'].choices = [(e.pk, f"{e.first_name}" ' ' f"{e.middle_name}" ' ' f"{e.last_name}") for e in AccusedPerson.objects.all()]
class Meta:
model = Court
fields = ['court_number', 'accused_person', 'court', 'court_verdict', 'scheduled_on']
views.py
def EditCourtInfo(request, id):
court = Court.objects.get(id=id)
if request.method == 'POST':
form = EditCourtInfoForm(request.POST)
if form.is_valid():
context = {'has_error': False}
court_number = form.cleaned_data['court_number']
accused_person = form.cleaned_data['accused_person']
court = form.cleaned_data['court']
court_verdict = form.cleaned_data['court_verdict']
scheduled_on = form.cleaned_data['scheduled_on']
print(scheduled_on)
court.court_number = court_number # The problem
court.accused_person = AccusedPerson.objects.get(pk=int(accused_person))
court.court = court
court.court_verdict = court_verdict
court.scheduled_on = scheduled_on
court.created_by = request.user.profile
if not context['has_error']:
court.save()
messages.success(request, '✅ Court Record Successfully Updated!')
return redirect('OfficerCourtInfo')
else:
messages.error(request, '⚠️ Court Record Was Not Updated!')
return redirect('EditCourtInfo', id=id)
else:
form = EditCourtInfoForm()
return render(request, 'Officer Edit Court.html', {'form':form, 'court':court})
CodePudding user response:
The immediate problem is that you have
court = Court.objects.get(id=id)
but then later
court = form.cleaned_data['court']
So you are re-using a variable for a different purpose. You could fix this problem by using a different variable for one of these. However, you are making this much more complicated than you need to. The form will already take care of editing the Court
object for you:
def EditCourtInfo(request, id):
court = Court.objects.get(id=id)
if request.method == 'POST':
form = EditCourtInfoForm(request.POST, instance=court). # pass the court object to the form
if form.is_valid():
form.save() # just save the form
messages.success(request, '✅ Court Record Successfully Updated!')
return redirect('OfficerCourtInfo')
else:
messages.error(request, '⚠️ Court Record Was Not Updated!')
return redirect('EditCourtInfo', id=id)
else:
form = EditCourtInfoForm()
return render(request, 'Officer Edit Court.html', {'form':form, 'court': court})
You will need to change your form to extend ModelForm
instead of Form
:
class EditCourtInfoForm(forms.ModelForm):
This code is untested, so I may have missed something. I suggest checking out the Django documentation to fill in any gaps in your understanding. You might even consider using a class-based view instead.