Why is my django function working when I test it in Postman but when I use my frontend its not?
I'm having an issue with creating a session in Django. The biggest issue is when debugging as the function works as expected when I run it in postman but not when I try to use my frontend which is built in React. I checked to make sure the data was being passed as expected and being received by the function in the backend and it is. But for some reason the session isn't working correctly. The code is outlined below.
In the views.py of my login app, the session is created in this function to track the user_id so that I can update the MongoDB document later on.
@api_view(['POST'])
def create_login(request):
# parse json
body = json.loads(request.body)
# get email and password and confirm password
email = body.get('email')
password = body.get('password')
confirm_password = body.get('confirm_password')
email_is_valid = False
password_is_valid = False
error = ''
# password must be at least 8 characters and contain digit 0 - 9, Uppercase, Lowercase and Special
# character from list (#?!@$%^&*-)
password_validation_pattern = re.compile('^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$')
# compare password to confirm password and regex pattern
if password == confirm_password and re.match(password_validation_pattern, password):
password_is_valid = True
elif password == confirm_password:
error = 'password is not valid. Requires at least one uppercase, lowercase, digit and special character [#?!@$%^&*-]'
else:
error = 'passwords do not match'
# verify email does not already exist in the database
if not users_collection.find_one({'email': email}):
email_is_valid = True
else:
error = 'email already exists'
# hash password before storing in database
hashed_password = make_password(password)
# save to database
if email_is_valid and password_is_valid:
document = users_collection.insert_one({
'email': email,
'password': hashed_password,
})
# create session to track the user id
user_id = document.inserted_id
request.session['user_id'] = str(user_id)
print(request.session['user_id'])
return JsonResponse(
{
'emailIsValid': email_is_valid,
'passwordIsValid': password_is_valid,
'errorMessage': error
}
)
In the same views.py I then access the session in a different function shown below:
@api_view(['POST'])
def add_core_user_details(request):
# parse json
body = json.loads(request.body)
# get all values
first_name = body.get('first_name')
last_name = body.get('last_name')
date_of_birth = body.get('date_of_birth')
gender = body.get('gender')
phone_number = body.get('phone_number')
athlete_or_coach = body.get('athlete_or_coach')
problem = ''
error_message = ''
# verify first and surname only have alphabetic values
if len(first_name) in [0, 1]:
problem = 'First Name'
error_message = 'First name is required and must contain more than 1 character'
elif not first_name.isalpha():
problem = 'First Name'
error_message = 'First name must only contain alphabetic characters'
if len(last_name) in [0, 1]:
problem = 'Last Name'
error_message = 'Last name is required and must contain more than 1 character'
elif not last_name.isalpha():
problem = 'Last Name'
error_message = 'Last name must only contain alphabetic characters'
# convert date_of_birth to type datetime
if date_of_birth is None:
problem = 'Date of Birth'
error_message = 'Date of birth is required'
else:
date_regex_pattern = re.compile(r'^(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[0-2])/[0-9]{4}$')
date_format = '%d/%m/%Y'
if re.match(date_regex_pattern, date_of_birth):
date_of_birth = datetime.strptime(date_of_birth, date_format)
else:
problem = 'Date of Birth'
error_message = 'Date in invalid format, must be DD/MM/YYYY'
# check gender is either male or female
if gender not in ['Male', 'Female']:
problem = 'Gender'
error_message = 'Must be either male or female'
# parse phone number to remove any non-numeric values
phone_number = re.sub(r'[^0-9]', '', phone_number)
if len(phone_number) not in [9, 10] or phone_number[0] != '0':
problem = 'Phone Number'
error_message = 'Invalid phone number'
# check athlete or coach is either athlete, coach or both
if athlete_or_coach not in ['Athlete', 'Coach', 'Both']:
problem = 'Athlete or Coach'
error_message = 'Must be either athlete, coach or both'
document = users_collection.find_one({"_id": bson.ObjectId(request.session['user_id'])})
if error_message == '' and problem == '':
# save to database
update = {'$set':{
'first_name': first_name,
'last_name': last_name,
'date_of_birth': date_of_birth,
'gender': gender,
'phone_number': phone_number,
'user_type': athlete_or_coach
}}
users_collection.update_one({"_id": bson.ObjectId(request.session['user_id'])}, update)
return JsonResponse({
'problem': problem,
'errorMessage': error_message
})
The data passed to this function is supposed to be added to the existing document created in the first function.
I put a print(request.session['user_id']) in the first function to see if I could access the session after it was created and I can. However, I cannot access it when using my frontend making a call to the latter function.
I'm really at a loss at this stage so any help would be greatly appreciated.
if you want to know what it looks like on the frontend here is the code below for the axios request:
export const updateUserDetails = async (...args: (string | number)[]) => {
// create an object called data that holds keys that are strings and corresponding values that are stings or numbers
const data: {[key: string]: string | number} = {};
for(let i = 0; i < args.length; i += 2) {
data[args[i]] = args[i+1];
}
try {
const response = await axios.post(
'http://localhost:8000/login-register/core-details/',
data
);
return response;
} catch (error) {
console.error('Error:', error);
}
}
And that function is called like this:
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const response = updateUserDetails('first_name', firstName, 'last_name', lastName, 'date_of_birth', dateOfBirth, 'gender', gender, 'phone_number', phoneNumber, 'athlete_or_coach', athleteOrCoach);
console.log(response);
}
return (
<form onSubmit={handleSubmit} className="flex items-center p-2 flex-col h-4/5 w-3/6 rounded-xl bg-z12-gray opacity-70">
<div className="text-3xl font-bold mt-6 tracking-wide">My Details</div>
<div className="grid grid-cols-2 grid-rows-3 w-full mt-3 overflow-auto">
<FormInputField title="First Name" name="firstname" type="text" changeHandler={setFirstName} paddingTop="pt-5" />
<FormInputField title="Surname" name="surname" type="text" changeHandler={setLastName} paddingTop="pt-5" />
<FormInputField title="Date of Birth" name="dob" type="text" placeholder="DD/MM/YYYY" changeHandler={setDateOfBirth} paddingTop="pt-5" />
<FormDropdown title="Gender" options={['Male', 'Female']} value={gender} changeHandler={setGender} paddingTop="pt-5" />
<FormInputField title="Phone Number" name="phonenumber" type="text" changeHandler={setPhoneNumber} paddingTop="pt-5" paddingBottom="pb-5" />
<FormDropdown title="Athlete or Coach?" options={['Athlete', 'Coach', 'Both']} value={athleteOrCoach} changeHandler={setAthleteOrCoach} paddingTop="pt-5" paddingBottom="pb-5" />
</div>
<SubmitButton title="Next" />
</form>
)
}