Nested function working but returning messages in Django

Issue

I have a function called inside another one.
The functions are working properly but, while using a validator to raise some error in case of wrong entries by the users, the validator works but is calling either the success and the error message.

I post some code for better explanation.

utils.py

def add_flight_function(request):
    try:
        aircraft_maintenance_type = AircraftMaintenanceType.objects.first()
    except:
        aircraft_maintenance_type = None
    aircraft = request.POST.get('aircraft')
    adep = request.POST.get('adep')
    ades = request.POST.get('ades')
    date = request.POST.get('date')
    atd = request.POST.get('atd')
    ata = request.POST.get('ata')
    function_type_obj = request.POST.get('function_type')
    function_type_obj = FunctionType.objects.get(id=function_type_obj)
    operational_condition = request.POST.get('operational_condition')
    student = request.POST.get('student')
    instructor = request.POST.get('instructor')
    night = request.POST.get('night')
    note = request.POST.get('note')
    aircraft_type = Aircraft.objects.get(
        id=aircraft).aircraft_type.abbreviation
    if aircraft_maintenance_type.is_tacho == True:
        atd_tacho = request.POST.get('atd_tacho')
        ata_tacho = request.POST.get('ata_tacho')
        if float(ata_tacho) <= float(atd_tacho):
            messages.error(
                request, "ATA Tacho cannot be lower than ATD Tacho")
            return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
        is_valid_flight, error_message = flight_validator(
            request, ata, atd, function_type_obj.name, instructor)
        if not is_valid_flight:
            messages.error(request, error_message)
            return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
    else:
        is_valid_flight, error_message = flight_validator(
            request, ata, atd, function_type_obj.name, instructor)
        if not is_valid_flight:
            messages.error(request, error_message)
            return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
    log_entry = LogEntry.objects.create(aircraft_id=aircraft, adep_id=adep, ades_id=ades, date=date, atd=atd,
                                        ata=ata, function_type_id=function_type_obj.id, student_id=student, instructor_id=instructor, operational_condition_id=operational_condition, note=note)
    if night == 'on':
        log_entry.night_flight = True
    # if function_type_obj.name == 'Dual Command':
    #     instructor_flight_payment = InstructorFlightPayment(log_entry=log_entry, instructor_id=instructor)
    #     instructor_flight_payment.save()
    if function_type_obj.name == 'Single Pilot':
        log_entry.solo_flight = True

    if aircraft_type == 'SIM':
        log_entry.sim_flight = True

    elif aircraft_type == 'MEP':
        log_entry.mep_flight = True
    log_entry.save()
    # This Part is for maintenance without Tachometer
    if aircraft_maintenance_type is None or aircraft_maintenance_type.is_tacho == False:
        ata_obj = parse(ata)
        atd_obj = parse(atd)
        if (ata_obj - atd_obj) > 10:
            maintenance_eet = timedelta(
                minutes=(ata_obj-atd_obj)) - timedelta(minutes=10)
        else:
            maintenance_eet = timedelta(minutes=(ata_obj-atd_obj))
        aircraft_flight_time = AircraftFlightTime(
            aircraft_id=aircraft, log_entry=log_entry, maintenance_eet=maintenance_eet)
        aircraft_flight_time.save()
    # This Part is for maintenance With Tachometer
    else:
        ata_obj = float(ata_tacho)
        atd_obj = float(atd_tacho)
        maint_eet_obj = (ata_obj - atd_obj) * 60

        maintenance_eet = timedelta(minutes=maint_eet_obj)

        aircraft_flight_time = AircraftFlightTime(
            aircraft_id=aircraft, log_entry=log_entry, maintenance_eet=maintenance_eet, atd_tacho=atd_tacho, ata_tacho=ata_tacho)
        aircraft_flight_time.save()

flight_validator:

def flight_validator(request, ata, etd, function_type, instructor):
    if ata <= etd:
        return False, "ATA cannot be greater or equal to ETD!"
    elif function_type == 'Dual Command' and not instructor:
        return False, "Instructor must be on Board!"
    return True, ""
    enter code here

views.py

def add_new_flight(request):
    aircrafts = Aircraft.objects.all()
    aerodromes = Aerodrome.objects.filter(is_base=False)
    base_aerodrome = Aerodrome.objects.get(is_base=True)
    function_type = FunctionType.objects.all()
    students = Student.objects.filter(is_active=True).order_by('last_name')
    instructors = Instructor.objects.filter(
        is_active=True).order_by('last_name')
    operational_conditions = OperationalCondition.objects.all()
    today = dt.today().date()
    try:
        aircraft_maintenance_type = AircraftMaintenanceType.objects.first()
    except:
        aircraft_maintenance_type = None
    context = {
        'aircrafts': aircrafts,
        'aerodromes': aerodromes,
        'function_type': function_type,
        'students': students,
        'instructors': instructors,
        'today': today,
        'operational_conditions': operational_conditions,
        'base_aerodrome': base_aerodrome,
        'aircraft_maintenance_type': aircraft_maintenance_type,
    }
    if request.method == 'POST':
        try:
            add_flight_function(request)
            messages.success(request, "New Flight Inserted Successfully")
            return HttpResponseRedirect(reverse('flight:flight_list'))
        except:
            messages.error(request, "Failed to Add New Flight")
            return HttpResponseRedirect(reverse('flight:add_new_flight'))
    return render(request, 'flight/add_new_flight.html', context)

If I make some input error, the validators are working properly but, for example, are showing both the error and success message. But, in fact, the success message shouldn’t be there and actually the function doesn’t work and doesn’t save anything.

Solution

I think that in your function add_flight_function you want to raise some kind of error so the code flow goes to the except block. Right now, you are returning a response instance which is not being used in your view and the code simply goes on to the next lines which add the success message and return a redirect (the try block).

So the fix would be to do this everywhere where you return HttpResponseRedirect in add_flight_function:

messages.error(request, error_message)
raise ValidationError(error_message)
# return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

Side note: it would be better if you used Django forms for all of this.

Answered By – vinkomlacic

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published