I am new to Django Rest Framework and checked some tutorials. Now I am trying to create my own structure which is like following. I want to create a user which is OK, then create a profile seperately.
models.py
class User(models.Model):
name = models.CharField(max_length=32)
surname = models.CharField(max_length=32)
facebook_id = models.TextField(null=True)
is_sms_verified = models.BooleanField(default=False)
created = models.DateTimeField(default=timezone.now)
updated = models.DateTimeField(default=timezone.now)
status = models.BooleanField(default=1)
def __str__(self):
return self.name+" "+self.surname
class Profile(models.Model):
user = models.ForeignKey('User',on_delete=models.CASCADE)
email = models.CharField(max_length=32)
birthday = models.DateField(null=True)
bio = models.TextField(null=True)
points = models.IntegerField(default=0)
created = models.DateTimeField(default=timezone.now)
updated = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.user.name+ " " + self.user.surname
serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model=User
fields = ('id','name','surname','facebook_id','is_sms_verified',)
read_only_fields = ('created','updated')
class ProfileSerializer(serializers.ModelSerializer):
user = UserSerializer(read_only=True)
class Meta:
model=Profile
fields=('id','user','email','birthday','bio','points')
read_only_fields = ('created','updated')
views.py
@api_view(['POST'])
def profile_create(request):
serializer = ProfileSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status = status.HTTP_201_CREATED)
return JsonResponse(serializer.errors , status= status.HTTP_400_BAD_REQUEST)
data I'm trying to post
{
"user_id": {
"id": 2
},
"email": "xxx@gmail.com",
"birthday": "1991-05-28",
"bio": "qudur",
"points": 31
}
The error I get;
NOT NULL constraint failed: core_profile.user_id
Where am I doing wrong? Thanks!
Your ProfileSerializer
has user
as readonly
. So you need to change that. I would suggest doing it like this
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model=Profile
fields=('id','user','email','birthday','gender','bio','points')
read_only_fields = ('created','updated')
def to_representation(self, instance):
self.fields['user'] = UserSerializer(read_only=True)
return super(ProfileSerializer, self).to_representation(instance)
If you do it this you could provide your user
as plain id for POST
{
"user": 2,
"email": "xxx@gmail.com",
"birthday": "1991-05-28",
"bio": "qudur",
"points": 31
}
And when you will read data it will look like this
{
"user": {
"id": 2,
"name": "Name",
"surname": "Surname",
...
},
"email": "xxx@gmail.com",
"birthday": "1991-05-28",
"bio": "qudur",
"points": 31
}
I've noticed Super()
throws an error the way it's mentioned above in the awnser:
return super(ProfileSerializer,self).to_representation(instance)
Error: Type error, object must be an instance or subtype of type
Try the Following:
Models.py
class Program(models.Model):
name = models.CharField(max_length=225)
cost = models.IntegerField(default=0)
description = models.TextField(default="", max_length=555)
class UserProgram(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
program = models.ForeignKey(Program, on_delete=models.CASCADE, related_name="program")
Serializers.py
class ProgramSerializers(serializers.ModelSerializer):
class Meta:
model = Program
fields = "__all__"
class UserProgramSerializers(serializers.ModelSerializer):
class Meta:
model = UserProgram
fields = "__all__"
#IMPORTANT PART
def to_representation(self, instance):
response = super().to_representation(instance)
response['program'] = ProgramSerializers(instance.program).data
return response
Views.py
class UserProgramViewset(viewsets.ModelViewSet):
permission_classes = [
permissions.IsAuthenticated
]
serializer_class = UserProgramSerializers
def get_queryset(self):
return UserProgram.objects.filter(user=self.request.user)
def perform_create(self, serializer):
serializer.save(user=self.request.user)
When you call the GET
request the following should be the output: GET Request Output
When you call the POST
request you only need to pass the programID and not the whole JSON dictionary!
Hope this helped.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.