I have two models user and notes, my aim is to get a JSON response like this.
{
"status": 200,
"data": [
{
"id": 1,
"note": "dd",
"created_on": "2022-10-03T06:58:33.337137Z",
"is_active": true,
"created_by":[{
"username":"loream",
"email":"[email protected]",
...........
}
]
},
]}
Modals are :
class Notes(models.Model):
note= models.TextField()
created_on=models.DateTimeField(auto_now_add=True)
is_active=models.BooleanField(default=True)
user=models.ForeignKey(UserModal,on_delete=models.CASCADE,null=True,related_name="created_byy",blank=True)
class UserModal(AbstractUser):
username = models.CharField(max_length=30,unique=True)
password = models.CharField(max_length=30)
email = models.EmailField(blank=True)
serializers I wrote is
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = UserModal
fields = '__all__'
class NotesSerializer(serializers.ModelSerializer):
created_byy = UserSerializer(many=True,read_only=True)
class Meta:
model=Notes
fields='__all__'
But I couldn't get a JSON response as expected I'm getting responses like this
{
"status": 200,
"data": [
{
"id": 1,
"note": "dd",
"created_on": "2022-10-03T06:58:33.337137Z",
"is_active": true,
"user": 1
},
]
}
how can I achieve the expected result?
CodePudding user response:
To fix this, change your serializer as follows:
class NotesSerializer(serializers.ModelSerializer):
user = UserSerializer(read_only=True) # user instead of created_byy, and no many=True
class Meta:
model = Notes
fields = '__all__'
Some explanations:
The problem you have is created_byy
does not exist in your Notes
model, it's the name of the attribute to get the queryset of notes from a user instance.
Basically, using user.created_byy.all()
would get you all notes related to this user.
Mode details about related_name in this post.
user
is the attribute you declared in your model, that's why you still retrieve it when using fields='__all__'
, and that's definitely the one you want.
If you really want your user to be named "created_by", just use a SerializerMethodField (docs here):
class NotesSerializer(serializers.ModelSerializer):
created_by = serializers.SerializerMethodField()
def get_created_by(self, instance):
return UserSerializer(instance.user)
class Meta:
model = Notes
fields = ['id', 'note', 'created_on', 'created_by', 'is_active']
Also, you cannot have an array of users in both cases, because of how you declared your one-to-many (one user can have several notes, the opposite is false).
On a final note, you really should rename the created_byy
to notes
so it's less confusing.
CodePudding user response:
@ThomasGth give you nice explanation.
Here is quick solution from me
class NotesSerializer(serializers.ModelSerializer):
created_by = UserSerializer(source='user', read_only=True)
class Meta:
model = Notes
fields = ['id', 'note', 'created_on', 'created_by', 'is_active']