Django form redirect if fields not unique.

Hi everyone. I am new to Django. I have a model which stores people and a one to one relationship to another table which stores details if the person is a visitor to our organization.

 
class Person(models.Model):
    createdBy = models.ForeignKey(User, models.CASCADE, null=True)
    Name = models.CharField(max_length=20, null=False, blank=False)
    Surname = models.CharField(max_length=20, null=False, blank=False)
    Gender = models.CharField(max_length=7, choices=GENDER, null=False, blank=True)
    CellNumber = models.CharField(max_length=10, null=False, blank=True)
    EmailAddress = models.EmailField(max_length=50, null=False, blank=True)
    date = models.DateTimeField(auto_now_add=True)
    area = models.CharField(max_length=20, null=False, blank=True)


class Meta:
        constraints = [
            models.UniqueConstraint(fields=['Name', 'Surname'], name="%(app_label)s_%(class)s_unique")
        ]

class visit_date(models.Model):
    visitor = models.OneToOneField(Person, models.CASCADE, null=True)
    createdby =  models.ForeignKey(User, models.CASCADE, null=True, blank=True)
    dateofvisit = models.DateTimeField(default=datetime.date.today())

I have a form to enter the person and the details of their visit using an inline form. Usually a visitors first visit will be their first interaction with our organization and the first time that person is saved in the database, but they might already have interacted with us and joined our mailing list before coming to visit. Currently when the user enters the existing person name and surname in the form if that name, surname combination exists in the form they get a message saying that the person already exists and the form is repopulated. I would like to redirect to another form where they can select from existing Persons in the database if this is the case and then if there is a different error on the form to have the usual redirect to display the form again. Is there a way to do this?

You’re already catching the condition of a duplicate name, so if that condition occurs, the view can return a redirect to a different view that displays your desired form to select the existing name.

Thank you. I am not sure how to capture that error statement so that I can use it to set the condition for the redirect statement.

Please post the view.

This is the view.

@login_required
def visitors(request):
    visitors = visit_date.objects.all()
    visitor_count = visit_date.objects.count()
    if request.method == 'POST':
        form_inline = visit_dateInlineFormset(request.POST)
        form = Form(request.POST)
        if form.is_valid() and form_inline.is_valid():
          instance = form.save(commit=False)
          instance.createdBy = User.objects.get(pk=request.user.pk)
          instance.save()
          form_inline.instance = instance
          form_inline.save()
          visitor_name = form.cleaned_data.get('Name')
          messages.success(request, f'{visitor_name} has been added')
          return redirect('visitors')
        else:
          print(form.errors, form_inline.errors)
    else:
       form_inline = visit_dateInlineFormset()
       form = PersonForm()
            
    context = {
        'form': form,
        'form_inline': form_inline,
        'visitors': visitors,
        'visitor_count': visitor_count

    }
    return render(request, 'visitors/visitors.html', context)

So for clarity, if the data is duplicated, are you executing this else clause?

Or is the error being thrown within the if form.is_valid() block?

If the former, you can interrogate form.errors to determine whether the error you wish to handle is in it.

If the latter, you can catch the exception and process it at that point.

I get the error by just running the is valid block. However when I use the

else:
          print(form.errors, form_inline.errors)

it displays an error message in my terminal when running the django runserver command.

The erorr message is

"<ul class="errorlist"><li>__all__<ul class="errorlist nonfield"><li>Peson with this Name and Surname already exists.</li></ul></li></ul> [{}]"

I’m not sure if this is the correct error message to use for a redirect in my view or which part of the error message to use.

Keep in mind that just printing something returns a string representation of an object - it may hide the actual structure of the underlying data.

In this situation, you have access to the form.errors object. If you read the information about that object and investigate the type of data it contains, you’ll see how you can make use of it for your needs.

Thank you very much. I’ll do that.