Home > Net >  How do I populate my database with a foreign key from Swagger UI?
How do I populate my database with a foreign key from Swagger UI?

Time:08-13

I am building an application with Django and I have a foreign key to a model named Dso in my custom user model.

Everything is all setup from the codebase, when I try to register a new user with my server GUI, I would see the connection there.

When I try to register a new user with Swagger UI, I normally would have to make a JSON dictionary input, something like this:

{
  "email": "[email protected]",
  "username": "example",
  "password": "example",
  "name": "example",
  "address": "My Address",
  "customerId": "example",
  "dso": 4,
  "roleId": 2
}

From the above, 4 is supposed to be an instance of the Dso model with id=4, but then swagger always returns an internal server error: Cannot assign "4": "User.dso" must be a "Dso" instance.

I don't know how to represent a foreign key relation in JSON.

Here is my code base:

UserModel:

class User(AbstractBaseUser, PermissionsMixin):
    dso = models.ForeignKey(to=Dso,related_name='dso',null=True,on_delete=models.CASCADE)
    name = models.CharField(max_length=70)
    address = models.CharField(max_length=70)
    roleId = models.IntegerField(default=1)
    customerId = models.CharField(max_length=70, blank=False, default='')
    username=models.CharField(max_length=255, unique=True, db_index=True)
    email=models.EmailField(max_length=255, unique=True, db_index=True)
    is_verified = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    is_trading = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    created_at=models.DateTimeField(auto_now_add=True)
    updated_at=models.DateTimeField(auto_now=True)

    @property
    def energy_data(self):
        energydata = EnergyData.objects.filter(customerId=self.customerId).first()
        return energydata
    
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username','name','address','roleId','customerId','dso']

    objects = UserManager()

    def __str__(self) -> str:
        return self.email

User Manager:

class UserManager(BaseUserManager):
    def create_user(self, username, email, name, address,roleId,customerId,dso,password=None):
        if username is None:
            raise TypeError('User should have a userame')
        if email is None:
            raise TypeError('Users should have a Email')
        
        user = self.model(username=username , email = self.normalize_email(email), name=name, address=address, roleId=roleId, customerId=customerId, dso=dso)
        user.set_password(password)
        user.save()
        return user

Dso Model:

class Dso(models.Model):
    supplier = models.CharField(max_length=70)

RegisterSerializer:

class RegisterSerializer(serializers.ModelSerializer):
    password = serializers.CharField(max_length = 68, min_length=6, write_only = True)
    name = serializers.CharField(max_length = 68, min_length=6)
    address = serializers.CharField(max_length = 68, min_length=6)
    customerId = serializers.CharField(max_length = 68, min_length=6)
    roleId = serializers.IntegerField()
    dso = serializers.IntegerField()
    
    class Meta:
        model=User
        fields=['email','username','password','name','address','customerId', 
                  'dso', 'roleId']
    
    def validate(self, attrs):
        email = attrs.get('email', '')
        username = attrs.get('username', '')
        name = attrs.get('name', '')
        address = attrs.get('address', '')
        customerId = attrs.get('customerId', '')

        if not len(username) >= 4:
            raise serializers.ValidationError('Username must be morethan 4 letters or characters')
        return attrs

    def create(self, validated_data):
        return User.objects.create_user(**validated_data)

UserSerializer:

class UserSerializer(serializers.ModelSerializer):
    energy_data = EnergyDataSerializer(read_only=True)
    dso = DsoSerializer(read_only = True)
    class Meta:
        model = User
        fields = ('__all__')
        depth = 1

Please your reply or answer would be of profound help... Thank You

CodePudding user response:

You must use PrimaryKeyRelatedField instead of IntegerField in your serializer:

class RegisterSerializer(serializers.ModelSerializer):
    password = serializers.CharField(max_length = 68, min_length=6, write_only = True)
    name = serializers.CharField(max_length = 68, min_length=6)
    address = serializers.CharField(max_length = 68, min_length=6)
    customerId = serializers.CharField(max_length = 68, min_length=6)
    roleId = serializers.IntegerField()
    dso = serializers.PrimaryKeyRelatedField(allow_null=True, queryset=Dso.objects.all())
    
    class Meta:
        model=User
        fields=['email','username','password','name','address','customerId', 
                  'dso', 'roleId']
    
    def validate(self, attrs):
        email = attrs.get('email', '')
        username = attrs.get('username', '')
        name = attrs.get('name', '')
        address = attrs.get('address', '')
        customerId = attrs.get('customerId', '')

        if not len(username) >= 4:
            raise serializers.ValidationError('Username must be morethan 4 letters or characters')
        return attrs

    def create(self, validated_data):
        return User.objects.create_user(**validated_data)
  • Related