I have a Profile model that has a one-to-one relationship with Django's User model, and I have another model, called Permission (unrelated to Django's internal idea of permissions), that has a foreign key to Profile. Like this: (I've removed most of the fields here, for simplicity)
from django.db import models
from django.contrib.auth.models import User as DjangoUser
class Account(models.Model):
name = models.CharField(max_length=200, db_index=True)
class Profile(models.Model):
django_user = models.OneToOneField(DjangoUser)
default_account = models.ForeignKey(Account)
class Permission(models.Model):
# Which user has the permission
user = models.ForeignKey(Profile, db_index=True)
# Which account they have the permission on
account = models.ForeignKey(Account, db_index=True)
I want to make a serializer for Permission, that will create objects like this:
{
"user": "[email protected]",
"account": 123
}
where the value of "account" is the account's primary key (so that's easy, I can use a PrimaryKeyRelatedField) and the value of "user" is the user's email address (this is the part I haven't figured out yet, because the email address is not stored directly on the Profile object, it's on the associated DjangoUser object). Note also that this is NOT read-only - when creating a Permission it does need to be able to deserialize from an email address to a Profile object.
Some things I have tried so far, for representing the user on the Permission serializer ...
1.
user = serializers.RelatedField(read_only=False)
With this one, if I POST an email address (or primary key or anything else) as the "user", it returns a 400 error saying {"user": "This field is required."}
, as if I didn't include the field at all.
2.
user = serializers.SlugRelatedField(slug_field='django_user.email')
With this one, I get AttributeError: 'Profile' object has no attribute 'django_user.email'
. Same thing happens if I use 'django_user__email'
.
Any ideas?
In function-based views, we can pass extra context to serializer with “context” parameter with a dictionary. To access the extra context data inside the serializer we can simply access it with “self. context”. From example, to get “exclude_email_list” we just used code 'exclude_email_list = self.
The SlugRelatedField provided by Django REST framework, like many of the related fields, is designed to be used with objects that already exist. Since you are looking to reference objects which already exist, or object which need to be created, you aren't going to be able to use it as-is.
As stated in the documentation, you will need to write your own create() and update() methods in your serializer to support writable nested data. You will also need to explicitly add the status field instead of using the depth argument otherwise I believe it won't be automatically added to validated_data .
If you want to show any field of foreign key instead of id then you can use StringRelatedField.
According to Django REST Framework serializer reference (http://www.django-rest-framework.org/api-guide/fields/#core-arguments):
The name of the attribute that will be used to populate the field. May be a method that only takes a self argument, such as URLField(source='get_absolute_url'), or may use dotted notation to traverse attributes, such as EmailField(source='user.email').
So, if source='user.email'
is not working, you can try to create a method (e.g. get_user_email
), use it in source
field and make it return the user email manually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With