Home > front end >  Django - AttributeError 'str' object has no attribute 'court_number'
Django - AttributeError 'str' object has no attribute 'court_number'

Time:02-25

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.

  • Related