Search code examples
djangopostgresqlamazon-web-servicesdjango-modelsdjango-rest-framework

Django rest framework does not save user to Postgres, no error


I have a project that is connected to a postgres db on AWS but when I go to create a user the user does not get saved. I was able to create a superuser with the python manage.py createsuperuser command. I can also see the superuser appear correctly in the database using PGAdmin.

Settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': env("POSTGRES_NAME"), 
        'USER': env("POSTGRES_USER"),
        'PASSWORD': env("POSTGRES_PASSWORD"),
        'HOST': env("POSTGRES_HOST"), 
        'PORT': env("POSTGRES_PORT"),
    }
}
DATABASES["default"]["ATOMIC_REQUESTS"] = True

models.py

class UserManager(BaseUserManager):
  def _create_user(self, email, password,first_name,last_name,is_staff, is_superuser, **extra_fields):
    if not email:
        raise ValueError('Users must have an email address')
    now = timezone.now()
    email = self.normalize_email(email)
    user = self.model(
        email=email,
        is_staff=is_staff, 
        is_active=True,
        is_superuser=is_superuser, 
        last_login=now,
        date_joined=now, 
        first_name = first_name,
        last_name = last_name,
        **extra_fields
    )
    user.set_password(password)
    user.save(using=self._db)
    return user

  def create_user(self, email, password, first_name, last_name, **extra_fields):
    user = self._create_user(email, password, first_name, last_name, False, False, **extra_fields)
    user.save(using=self._db)
    return user
    # return self._create_user(email, password, first_name, last_name, False, False, **extra_fields)

  def create_superuser(self, email, password, **extra_fields):
    user=self._create_user(email, password, None, None, True, True, **extra_fields)
    user.save(using=self._db)
    return user


# Custom user model
class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=254, unique=True)
    name = models.CharField(max_length=254, null=True, blank=True)
    first_name = models.CharField(max_length=254, null=True, blank=True)
    last_name = models.CharField(max_length=254, null=True, blank=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)

serializer.py

class UserSerializer(ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'
        extra_kwargs = {
            'password': {'write_only': True},
            'id': {'read_only': True}
        }

    # called when we create a user
    def create(self, validated_data):
        password = validated_data.pop('password', None)
        # user itself
        instance = self.Meta.model(**validated_data)
        if password is not None:
            instance.set_password(password)

        instance.save()
        return instance

views.py

class RegisterAPIView(APIView):
    def post(self, request):
        data = request.data
        print("here data")
        print(data)
        if data['password'] != data['password_confirm']:
            raise exceptions.APIException('Passwords do not match!')
        serializer = UserSerializer(data=data)
        serializer.is_valid(raise_exception=True)
        user_id = serializer.save()
        # serializer.save()
        print('errors:', serializer.errors)
        return Response(serializer.data,status=status.HTTP_200_OK)

Post Request

{
    "first_name": "firstName",
    "last_name": "lastName",
    "email": "[email protected]",
    "password": "password123",
    "password_confirm": "password123"
}

Post Response

{
    "id": 15,
    "first_name": "firstName",
    "last_name": "lastName",
    "email": "[email protected]",
}

Terminal

here data
{'first_name': 'firstName', 'last_name': 'lastName', 'email': '[email protected]', 'password': 'password123', 'password_confirm': 'password123'}
errors: {}

Strangely the id keeps ticking up even though an entry is not made to the database. I want to say the issue is somewhere between my view and the serializer since the superuser was able to be created successfully.

Another Edit: I did some more digging and discovered that this works with my sqlitedb and seems to be an issue with RDS Postgres. This issue seems somewhat related


Solution

  • My mistake was apparently turning on atomic requests. I have to dig into this a lot more. I don't understand why this is making it fail.