sei-ec-remote / project-4-issues

Open an issue to receive help on project 4
0 stars 0 forks source link

Sign-Up Post from React to Django - all validation fields present but bad request 400 42 #214

Closed estebbins closed 1 year ago

estebbins commented 1 year ago

What stack are you using?

(ex: MERN(mongoose + react), DR(django + react), PEN, etc.)

DR

What's the problem you're trying to solve?

I am getting a POST 400 42 error when trying to sign up a new user.

Post any code you think might be relevant (one fenced block per file)

class UserRegisterSerializer(serializers.Serializer):
    # Require email, password, and password_confirmation for sign up
    email = serializers.CharField(max_length=300, required=True)
    username = serializers.CharField(max_length=300, required=True)
    phone_number = serializers.CharField(max_length=12, required=True)
    password = serializers.CharField(required=True)
    password_confirmation = serializers.CharField(required=True, write_only=True)

    def validate(self, data):
        # Ensure password & password_confirmation exist
        if not data['password'] or not data['password_confirmation']:
            raise serializers.ValidationError('Please include a password and password confirmation.')

        # Ensure password & password_confirmation match
        if data['password'] != data['password_confirmation']:
            raise serializers.ValidationError('Please make sure your passwords match.')
        # if all is well, return the data
        return data

If you see an error message, post it here. If you don't, what unexpected behavior are you seeing?

"POST /sign-up/ HTTP/1.1" 400 42

email = CharField(max_length=300, required=True)
username = CharField(max_length=300, required=True)
phone_number = CharField(max_length=12, required=True)
password = CharField(required=True)
password_confirmation = CharField(required=True, write_only=True)

Bad Request: /sign-up/ [09/Mar/2023 01:11:06] "POST /sign-up/ HTTP/1.1" 400 42

What is your best guess as to the source of the problem?

I am not sure, I have printed and consoled everything and it looks correct

What things have you already tried to solve the problem?

Fixed user validation/serialization between front and back.

Paste a link to your repository here https://github.com/estebbins/FareIsFair-API

timmshinbone commented 1 year ago

Share the code from the react side

estebbins commented 1 year ago

I just renamed the field to screenname - now I am getting this error: [09/Mar/2023 15:22:20] "POST /sign-up/ HTTP/1.1" 500 178951 request {'credentials': {'email': 'testuser12@test.test', 'screenname': 'testuser12', 'phone_number': '0000000000', 'password': 'donuttest1', 'password_confirmation': 'donuttest1'}} user UserRegisterSerializer(data={'email': 'testuser12@test.test', 'screenname': 'testuser12', 'phone_number': '10000000000', 'password': 'donuttest1', 'password_confirmation': 'donuttest1'}): email = CharField(max_length=300, required=True) screenname = CharField(max_length=300, required=True) phone_number = CharField(max_length=12, required=True) password = CharField(required=True) password_confirmation = CharField(required=True, write_only=True) created_user UserSerializer(data={'email': 'testuser12@test.test', 'screenname': 'testuser12', 'phone_number': '10000000000', 'password': 'donuttest1'}): id = IntegerField(label='ID', read_only=True) email = EmailField(max_length=255, validators=[<UniqueValidator(queryset=User.objects.all())>]) screenname = CharField(max_length=25, validators=[<UniqueValidator(queryset=User.objects.all())>]) phone_number = CharField(max_length=12) password = CharField(max_length=128, min_length=5, write_only=True) modelbefore <class 'api.models.user.User'> modelafter <class 'api.models.user.User'> Internal Server Error: /sign-up/ Traceback (most recent call last): File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/db/backends/utils.py", line 89, in _execute return self.cursor.execute(sql, params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ psycopg2.errors.UniqueViolation: duplicate key value violates unique constraint "api_user_username_key" DETAIL: Key (screenname)=() already exists.

The above exception was the direct cause of the following exception:

Traceback (most recent call last): File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/core/handlers/exception.py", line 56, in inner response = get_response(request) ^^^^^^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, callback_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/views/decorators/csrf.py", line 55, in wrapped_view return view_func(*args, *kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/views/generic/base.py", line 103, in view return self.dispatch(request, args, kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/rest_framework/views.py", line 509, in dispatch response = self.handle_exception(exc) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/rest_framework/views.py", line 469, in handle_exception self.raise_uncaught_exception(exc) File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception raise exc File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/rest_framework/views.py", line 506, in dispatch response = handler(request, args, kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/sei_fruitcakes/django-env/fare_is_fair_api/api/views/user_views.py", line 37, in post created_user.save() File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/rest_framework/serializers.py", line 212, in save self.instance = self.create(validated_data) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/sei_fruitcakes/django-env/fare_is_fair_api/api/serializers.py", line 51, in create return get_user_model().objects.create_user(validated_data) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/sei_fruitcakes/django-env/fare_is_fair_api/api/models/user.py", line 38, in create_user user.save() File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/contrib/auth/base_user.py", line 68, in save super().save(args, *kwargs) File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/db/models/base.py", line 812, in save self.save_base( File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/db/models/base.py", line 863, in save_base updated = self._save_table( ^^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/db/models/base.py", line 1006, in _save_table results = self._do_insert( ^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/db/models/base.py", line 1047, in _do_insert return manager._insert( ^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/db/models/manager.py", line 85, in manager_method return getattr(self.get_queryset(), name)(args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/db/models/query.py", line 1791, in _insert return query.get_compiler(using=using).execute_sql(returning_fields) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1660, in execute_sql cursor.execute(sql, params) File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/db/backends/utils.py", line 102, in execute return super().execute(sql, params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/db/backends/utils.py", line 67, in execute return self._execute_with_wrappers( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers return executor(sql, params, many, context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/db/backends/utils.py", line 84, in _execute with self.db.wrap_database_errors: File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/db/utils.py", line 91, in exit raise dj_exc_value.with_traceback(traceback) from exc_value File "/Users/emilystebbins/.local/share/virtualenvs/django-env-YZLzXMbs/lib/python3.11/site-packages/django/db/backends/utils.py", line 89, in _execute return self.cursor.execute(sql, params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ django.db.utils.IntegrityError: duplicate key value violates unique constraint "api_user_username_key" DETAIL: Key (screenname)=() already exists.

export const signUp = (credentials) => {
    console.log('credentials at axios', credentials)
    return axios({
        method: 'POST',
        url: apiUrl + '/sign-up/',
        data: {
            credentials: {
                email: credentials.email,
                screenname: credentials.screenname,
                phone_number: credentials.phoneNumber,
                password: credentials.password,
                password_confirmation: credentials.passwordConfirmation,
            },
        },
    })
}
// import React, { Component } from 'react'
import React, { useState } from 'react'
import { useNavigate } from 'react-router-dom'

import { signUp, signIn } from '../../api/auth'
import messages from '../shared/AutoDismissAlert/messages'

import Form from 'react-bootstrap/Form'
import Button from 'react-bootstrap/Button'

const SignUp = (props) => {
    // constructor(props) {
    //  super(props)

    //  this.state = {
    //      email: '',
    //      password: '',
    //      passwordConfirmation: '',
    //  }
    // }    
    const [email, setEmail] = useState('')
    const [password, setPassword] = useState('')
    const [passwordConfirmation, setPasswordConfirmation] = useState('')
    const [screenname, setScreenname] = useState('')
    const [phoneNumber, setPhoneNumber] = useState('')

    const navigate = useNavigate()

    const onSignUp = (event) => {
        event.preventDefault()

        const { msgAlert, setUser } = props

        const credentials = {email, password, passwordConfirmation, screenname, phoneNumber}

        signUp(credentials)
            .then(() => signIn(credentials))
            .then((res) => setUser(res.data.user))
            .then(() =>
                msgAlert({
                    heading: 'Sign Up Success',
                    message: messages.signUpSuccess,
                    variant: 'success',
                })
            )
            .then(() => navigate('/'))
            .catch((error) => {
                setEmail('')
                setPassword('')
                setPasswordConfirmation('')
                setScreenname('')
                setPhoneNumber('')
                msgAlert({
                    heading: 'Sign Up Failed with error: ' + error.message,
                    message: messages.signUpFailure,
                    variant: 'danger',
                })
            })
    }

    return (
        <div className='row'>
            <div className='col-sm-10 col-md-8 mx-auto mt-5'>
                <h3>Sign Up</h3>
                <Form onSubmit={onSignUp}>
                    <Form.Group controlId='email'>
                        <Form.Label>Email address</Form.Label>
                        <Form.Control
                            required
                            type='email'
                            name='email'
                            value={email}
                            placeholder='Enter email'
                            onChange={e => setEmail(e.target.value)}
                        />
                    </Form.Group>
                    <Form.Group controlId='screenname'>
                        <Form.Label>Screenname</Form.Label>
                        <Form.Control
                            required
                            name='screenname'
                            value={screenname}
                            type='text'
                            placeholder='screenname'
                            onChange={e => setScreenname(e.target.value)}
                        />
                    </Form.Group>
                    <Form.Group controlId='phone_number'>
                        <Form.Label>Phone Number</Form.Label>
                        <Form.Control
                            required
                            name='phone_number'
                            value={phoneNumber}
                            type='phone'
                            placeholder=''
                            onChange={e => setPhoneNumber(e.target.value)}
                        />
                    </Form.Group>
                    <Form.Group controlId='password'>
                        <Form.Label>Password</Form.Label>
                        <Form.Control
                            required
                            name='password'
                            value={password}
                            type='password'
                            placeholder='Password'
                            onChange={e => setPassword(e.target.value)}
                        />
                    </Form.Group>
                    <Form.Group controlId='passwordConfirmation'>
                        <Form.Label>Password Confirmation</Form.Label>
                        <Form.Control
                            required
                            name='passwordConfirmation'
                            value={passwordConfirmation}
                            type='password'
                            placeholder='Confirm Password'
                            onChange={e => setPasswordConfirmation(e.target.value)}
                        />
                    </Form.Group>
                    <Button variant='primary' type='submit'>
                        Submit
                    </Button>
                </Form>
            </div>
        </div>
    )

}

export default SignUp
estebbins commented 1 year ago

Finally was able to identify that I was missing the additional arguments here ( I had previously tried something similar, but believe I was referring to them incorrectly)

        user = self.model(email=self.normalize_email(email), screenname=screenname, phone_number=phone_number, **extra_fields)