I'm using Django 2.0 and Django REST Framework to write REST API.
My contacts/models.py contains
class Contact(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100, blank=True, null=True)
date_of_birth = models.DateField(blank=True, null=True)
avatar = models.ImageField(upload_to='contact/%Y/%m/%d', blank=True)
class Meta:
db_table = 'contacts'
class ContactPhoneNumber(models.Model):
contact = models.ForeignKey(Contact, on_delete=models.CASCADE)
phone = models.CharField(max_length=100)
class Meta:
db_table = 'contact_phone_numbers'
and contacts/serializers.py
class ContactPhoneNumberSerializer(serializers.ModelSerializer):
class Meta:
model = ContactPhoneNumber
fields = ('id', 'phone', 'primary', 'created', 'modified')
class ContactSerializer(serializers.HyperlinkedModelSerializer):
phone_numbers = ContactPhoneNumberSerializer(source='contactphonenumber_set', many=True)
url = serializers.HyperlinkedRelatedField(
view_name='contacts:detail',
read_only=True
)
class Meta:
model = Contact
fields = ('url', 'id', 'first_name', 'last_name', 'date_of_birth', 'avatar', 'phone_numbers')
def create(self, validated_data):
print(validated_data)
instance = Contact.objects.create(**validated_data)
instance.save()
return instance
I want to be able to create contact along with phone_number and one contact can have many phone_numbers.
But when I send POST request with only contact data, it gives error as
'contactphonenumber_set' is an invalid keyword argument for this function
on calling contacts only is showing all associted mobile numbers in json response but unable to create record.
print(validated_data) gives following data
{'first_name': 'Anshuman', 'last_name': 'Upadhyay', 'date_of_birth': datetime.date(2018, 5, 15), 'contactphonenumber_set': [], 'user_id': <SimpleLazyObject: <User: anuj>>}
How can I create related multiple fields with REST Framework?
You cannot pass contactphonenumber_set to objects.create() method directly. You should create each related phonenumber separately, like this:
def create(self, validated_data):
print(validated_data)
phone_numbers = validated_data.pop('contactphonenumber_set')
instance = Contact.objects.create(**validated_data)
for phone_data in phone_numbers:
ContactPhoneNumber.objects.create(contact=instance, **phone_data)
return instance
See details about writable nested serializers here.
Give you a demo with drf-writable-nested
models.py:
class UnitGroup(models.Model):
name = models.CharField(max_length=255,
verbose_name='名称')
class Unit(models.Model):
unit_group = models.ForeignKey('medicine.UnitGroup',
related_name='unit_unit_group',
null=True,
on_delete=models.SET_NULL,
verbose_name='unit_group')
name = models.CharField(max_length=255,
verbose_name='name')
display_name = models.CharField(max_length=255,
verbose_name='display_name')
serializers.py:
class UnitCreateSerializer(ModelSerializer):
class Meta:
model = Unit
fields = ('name', 'display_name', 'ratio', 'is_active')
class UnitGroupCreateSerializer(WritableNestedModelSerializer):
unit_unit_group = UnitCreateSerializer(many=True)
class Meta:
model = UnitGroup
fields = ('unit_unit_group', 'name')
tests.py:
class UnitGroupTests(APITestCase):
def setUp(self):
try:
self.user = User.objects.get(tel='18094213198')
except User.DoesNotExist:
self.user = User.objects.create_user(tel='18094213198', password='123456')
self.user.user_permissions.add(*get_model_permission(UnitGroup))
token, _ = Token.objects.get_or_create(user=self.user)
self.access_token = token.access_token
def test_create(self):
"""create"""
url = reverse('unitgroup-list')
self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.access_token)
data = {'name': 'Widget', 'unit_unit_group': [{'name': '1', 'display_name': 'yi'}]}
response = self.client.post(url, data, format='json')
print([(x, x.unit_group) for x in Unit.objects.all()])
print('create', json.dumps(response.data, ensure_ascii=False, indent=2))
self.assertEqual(response.status_code, status.HTTP_200_OK)
test output:
[(<Unit: 1>, <UnitGroup: Widget>)]
create{
"id": 1,
"name": "Widget",
"create_time": "2018-05-08 16:59:51",
"update_time": "2018-05-08 16:59:51"
}
Related
During serialization, i noticed that the post_author Foreign Key of the Post model is referencing the id of the creator and thus, i can't display the username of the creator in the REST API, only the post_author id.
How can i add the username of the post_creator, so that it is readable to other users, when i fetch the data on the frontend?
models.py // CustomUser = the Creator of the post.
class CustomUser(AbstractUser):
fav_color = models.CharField(blank=True, max_length=120)
class Post(models.Model):
post_author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='posts')
post_title = models.CharField(max_length=200)
post_body = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def __str__(self):
return self.post_title
views.py
#api_view(['GET'])
def post_list(request):
posts = Post.objects.all()
serializer = PostSerializer(posts, many=True)
return Response(serializer.data)
serializers.py user model and post model serialization
class CustomUserSerializer(serializers.ModelSerializer):
"""
Currently unused in preference of the below.
"""
email = serializers.EmailField(required=True)
username = serializers.CharField()
password = serializers.CharField(min_length=8, write_only=True)
class Meta:
model = CustomUser
fields = ('email', 'username', 'password')
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
password = validated_data.pop('password', None)
# as long as the fields are the same, we can just use this
instance = self.Meta.model(**validated_data)
if password is not None:
instance.set_password(password)
instance.save()
return instance
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = '__all__'
single post from the API
{
"id": 1,
"post_title": "first_post",
"post_body": "qwe1",
"created_date": "2020-11-17T19:30:55Z",
"published_date": null,
"post_author": 1
},
You need to override the serializer:
class PostSerializer(serializers.ModelSerializer):
post_author_username = serializers.ReadOnlyField(source="post_author.username")
class Meta:
model = Post
fields = [post_author_username, post_title, post_body, created_data, published_data]
You can to specify the post_author serializer in your PostSerializer:
class PostSerializer(serializers.ModelSerializer):
post_author=CustomUserSerializer(read_only=True)
class Meta:
model = Post
fields = '__all__'
You can see the documentation here
i have the below config and i would like to map the url field in UserProfileView to the related user's username instead of the default pk field
currently the url looks likes below, appreciate any help
{
"user": 23,
"bio": "My bio",
"created_on": "2020-06-12T21:24:52.746329Z",
"url": "http://localhost:8000/bookshop/bio/8/?format=api"
},
what i am looking for is
{
"user": 23, <--- this is the user <pk>
"bio": "My bio",
"created_on": "2020-06-12T21:24:52.746329Z",
"url": "http://localhost:8000/bookshop/bio/username/?format=api"
},
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
bio = models.CharField(max_length=255)
created_on = models.DateTimeField(auto_now_add=True)
last_updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.user.username
views.py
class UserProfileViewSets(viewsets.ModelViewSet):
authentication_classes = [TokenAuthentication, ]
permission_classes = [rest_permissions.IsAuthenticated, permissions.UserProfileOwnerUpdate, ]
queryset = models.UserProfile.objects.all()
serializer_class = serializers.UserProfileSerializer
renderer_classes = [renderers.AdminRenderer, renderers.JSONRenderer, renderers.BrowsableAPIRenderer, ]
# lookup_field = 'user.username'
def perform_create(self, serializer):
serializer.save(user=self.request.user)
serializer.py
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserProfile
fields = ['user', 'bio', 'created_on', 'url']
extra_kwargs = {
'last_updated': {
'read_only': True
},
'user': {
'read_only': True
},
}
after struggling and reading many articles, I did it and posting down the solution if anybody was looking for the same use case.
the fields are being related to each other by OneToOne relationship
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
bio = models.CharField(max_length=255)
created_on = models.DateTimeField(auto_now_add=True)
last_updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.user.username
class User(AbstractBaseUser, PermissionsMixin):
""""
Customizes the default user account
"""
email = models.EmailField(unique=True, help_text='username is the email address')
first_name = models.CharField(max_length=40, blank=False)
last_name = models.CharField(max_length=40, blank=False)
date_joined = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
username = models.CharField(max_length=15, unique=True, null=True, blank=False,
validators=(validators.UnicodeUsernameValidator, ))
is_borrower = models.BooleanField(default=False)
The serializer is a HyperlinkedModelSerializer, as shown below the user SerializerField is PrimaryKeyRelatedField and it is being related to another column/field in the User model user.username - i made this as the default PrimaryKeyRelatedField is the pk and i dont want to expose that on the API
the url key is customized to be HyperlinkedRelatedField to point to the above field - the user with a viewname user-related
serializer.py
class UserProfileSerializer(serializers.HyperlinkedModelSerializer):
user = serializers.PrimaryKeyRelatedField(source='user.username', read_only=True)
url = serializers.HyperlinkedRelatedField(read_only=True, view_name='user-detail', )
class Meta:
model = models.UserProfile
fields = ['user', 'bio', 'created_on', 'url']
extra_kwargs = {
'last_updated': {
'read_only': True
},
'user': {
'read_only': True
},
}
on the views, i defined the lookup_field to be user and override the get_object method as now the queryset should be filtered by the username
views.py
class UserProfileViewSets(viewsets.ModelViewSet):
authentication_classes = [TokenAuthentication, ]
permission_classes = [rest_permissions.IsAuthenticated, permissions.UserProfileOwnerUpdate, ]
queryset = models.UserProfile.objects.all()
serializer_class = serializers.UserProfileSerializer
renderer_classes = [renderers.AdminRenderer, renderers.JSONRenderer, renderers.BrowsableAPIRenderer, ]
lookup_field = 'user'
def perform_create(self, serializer):
serializer.save(user=self.request.user)
def get_object(self):
queryset = self.filter_queryset(models.UserProfile.objects.get(user__username=self.kwargs.get('user')))
return queryset
EDIT:
I did the requirements in another approach and think this one is more neat way , so below the modifications.
You need to create anew customized HyperLinkedIdentityField where you over right the kwargs, check the below kwargs, the value is mapped to the related model where a OneToOneForgienKey deifined
class AuthorHyperLinkedIdentityField(serializers.HyperlinkedIdentityField):
def get_url(self, obj, view_name, request, format):
if hasattr(obj, 'pk') and obj.pk is None:
return None
return self.reverse(view_name, kwargs={
'obj_username': obj.author.username
}, format=format, request=request)
on the view you overright the lookup_field with the kwargs defined in the CustomizedField
class AuthorViewSet(viewsets.ModelViewSet):
serializer_class = serializers.AuthorSerializer
queryset = models.Author.objects.all()
renderer_classes = [renderers.JSONRenderer, renderers.BrowsableAPIRenderer, renderers.AdminRenderer]
# the below is not used but i keep it for reference
# lookup_field = 'author__username'
# the below should match the kwargs in the customized HyperLinkedIdentityField
lookup_field = 'obj_username'
The final serializer would look like
class AuthorSerializer(serializers.HyperlinkedModelSerializer):
"""
Serializers Author Model
"""
# first_name = serializers.SlugRelatedField(source='author', slug_field='first_name',
# read_only=True)
# last_name = serializers.SlugRelatedField(source='author', slug_field='last_name',
# read_only=True)
author = serializers.PrimaryKeyRelatedField(queryset=models.User.objects.filter(groups__name='Authors'),
write_only=True)
name = serializers.SerializerMethodField()
username = serializers.PrimaryKeyRelatedField(source='author.username', read_only=True)
# the below commented line is building the URL field based on the lookup_field = username
# which takes its value from the username PrimaryKeyRelatedField above
# url = serializers.HyperlinkedRelatedField(view_name='user-detail', read_only=True)
url = AuthorHyperLinkedIdentityField(view_name='author-detail', read_only=True)
class Meta:
model = models.Author
fields = ['author', 'name', 'username', 'url', ]
def get_name(self, author):
return '%s %s' % (author.author.first_name, author.author.last_name)
below the Author Model for your reference
class Author(models.Model):
"""
A Model to store the Authors info
"""
author = models.OneToOneField(User, on_delete=models.CASCADE, related_name='authors')
is_author = models.BooleanField(default=True, editable=True, )
class Meta:
constraints = [
models.UniqueConstraint(fields=['author'], name='check_unique_author')
]
def __str__(self):
return '%s %s' % (self.author.first_name, self.author.last_name)
def author_full_name(self):
return '%s %s' % (self.author.first_name, self.author.last_name)
I'm using Djago 2.0 and Django REST Framework
I have following model classes for contacts/models.py
class Contact(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100, blank=True, null=True)
date_of_birth = models.DateField(blank=True, null=True)
class ContactPhoneNumber(models.Model):
contact = models.ForeignKey(Contact, on_delete=models.CASCADE)
phone = models.CharField(max_length=100)
primary = models.BooleanField(default=False)
contacts/views.py
class ContactViewSet(viewsets.ModelViewSet):
serializer_class = ContactSerializer
permission_classes = (IsAuthenticated, AdminAuthenticationPermission,)
def get_queryset(self):
return Contact.objects.filter(user=self.request.user)
def perform_create(self, serializer):
serializer.save(user_id=self.request.user)
and contacts/serializers.py is defined as
class ContactPhoneNumberSerializer(serializers.ModelSerializer):
class Meta:
model = ContactPhoneNumber
fields = ('id', 'phone', 'primary', 'created', 'modified')
class ContactSerializer(serializers.HyperlinkedModelSerializer):
phone_numbers = ContactPhoneNumberSerializer(source='contactphonenumber_set', many=True)
user = serializers.CurrentUserDefault()
class Meta:
model = Contact
fields = ('url', 'id', 'first_name', 'last_name', 'date_of_birth', 'phone_numbers')
def create(self, validated_data):
phone_numbers = validated_data.pop('contactphonenumber_set')
user = validated_data.pop('user_id')
instance = Contact.objects.create(
user=user,
**validated_data
)
for phone_data in phone_numbers:
ContactPhoneNumber.objects.create(contact=instance, **phone_data)
return instance
I want to be able to create multiple phone_number instances with new contact object.
How can I pass multiple phone_numbers with fields phone, primary along with contact data?
Your JSON Post body needs to look like this:
{
"user": 1,
"first_name": "Anuj",
"last_name": "TBE",
"date_of_birth": "1990-01-01",
"contactphonenumber_set": [
{
"phone": "+91999999999",
"primary": false
},
{
"phone": "+91999999993",
"primary": true
}
]
}
Do think about how you want to deal with duplicates in this context.
I've simplified my code to make problem more clear.
I have two related models in my Django REST project. In my models.py:
class ClinicalResearch(models.Model):
name = models.CharField(max_length=150, null=True)
description = models.TextField(blank=True, null=True)
class Patient(models.Model):
research = models.ForeignKey(ClinicalResearch, on_delete=models.CASCADE, blank=True)
first_name = models.CharField(max_length=50)
second_name = models.CharField(max_length=50, blank=True, null=True)
middle_name = models.CharField(max_length=50, blank=True, null=True)
location = models.CharField(max_length=50, blank=True)
birth_date = models.DateTimeField(blank=True, null=True)
observation_date = models.DateTimeField(blank=True, null=True)
desease = models.CharField(max_length=50, blank=True, null=True)
desease_date = models.DateTimeField(blank=True, null=True)
gender = models.CharField(max_length=10)
Then I create a serialiser:
class PatientSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Patient
fields = ('id', 'research_id', 'first_name', 'second_name', 'middle_name', 'location', 'birth_date', 'observation_date', 'desease', 'desease_date', 'gender')
def create(self, validated_data):
# for tests only
print(validated_data)
return Patient(**validated_data)
View set:
class PatientViewSet(viewsets.ModelViewSet):
queryset = Patient.objects.all()
serializer_class = PatientSerializer
filter_backends = (DjangoFilterBackend,)
filter_fields = ('id', 'research_id', 'first_name', 'second_name', 'middle_name', 'location', 'birth_date', 'observation_date', 'desease', 'desease_date', 'gender')
Router:
router.register(r'patients', ItemViewSet)
This implementation works fine for models without foreign keys. But when I post something like:
{
'id': null,
'research_id': 1,
'first_name': "john",
'second_name': "doe",
'middle_name', "",
'location': "Love Street",
'birth_date': "...",
'observation_date': "...",
'desease': "Lovefool",
'desease_date': "...",
"gender": "male to fem"
}
(the project with id=1 exists)
my ItemSerializer doesn't pass { research_id: 1 } to validated_fields.
The project_id field is completely lost during validation.
How to configure Serializer or ViewSet to make it workable?
Looks like problem related to HyperlinkedModelSerializer in this case Django expecting url for related object instead of id. Try to override type of serializer's field research:
class PatientSerializer(serializers.HyperlinkedModelSerializer):
research = serializers.PrimaryKeyRelatedField()
class Meta:
model = Patient
fields = ('id', 'research', 'first_name', 'second_name', 'middle_name', 'location', 'birth_date', 'observation_date', 'desease', 'desease_date', 'gender')
def create(self, validated_data):
# for tests only
print(validated_data)
return Patient(**validated_data)
# If you need URLs for representation use this method
def to_representation(self, instance):
"""Set field type for output only"""
self.fields['research'] = serializers.HyperlinkedRelatedField()
return super().to_representation(instance)
You have to link it:
accept
Looks like problem related to HyperlinkedModelSerializer in this case Django expecting url for related object instead of id. Try to override type of serializer's field research:
class PatientSerializer(serializers.ModelSerializer):
research = serializers.PrimaryKeyRelatedField(queryset=ClinicalResearch.objects.all())
class Meta:
model = Patient
fields = ('id', 'research', 'first_name', 'second_name', 'middle_name', 'location', 'birth_date', 'observation_date', 'desease', 'desease_date', 'gender')
def create(self, validated_data):
# for tests only
print(validated_data)
return Patient.objects.create(**validated_data)
2nd Screenshot of APIAPI Sample Screenshot
I'm New in Django, i want to help regarding validations in screenshot there is company_name, location, title and user_location fields except user info with proper validation
but i want to remove validations from company_name, location, title and user_location fields how to do?
Please find the above api screenshot and
Please find the below scripts,
views.py
class UserRegistrationView(generics.CreateAPIView):
"""
Register a new user.
"""
queryset = User.objects.all()
permission_classes = (permissions.AllowAny, )
def get_serializer_class(self, user_type=None):
if user_type == 'student':
return StudentRegistrationSerializer
return ProfessionalRegistrationSerializer
def post(self, request, user_type=None, format=None):
serializer_class = self.get_serializer_class(user_type)
serializer = serializer_class(data=request.data, context={'request': request})
if serializer.is_valid(raise_exception=True)
user = serializer.save(work_status=user_type)
token, created = Token.objects.get_or_create(user=user)
data = BasicUserSerializer(user, context={'request': request}).data
data.update({"token": token.key})
return Response(data)
serializes.py
class ProfessionalRegistrationSerializer(serializers.HyperlinkedModelSerializer):
password = serializers.CharField(max_length=20, write_only=True)
experiences = ExperienceSerializer(required=False)
email = serializers.EmailField()
first_name = serializers.CharField(max_length=30)
last_name = serializers.CharField(max_length=30)
class Meta:
model = User
fields = ('url', 'id', 'first_name', 'last_name', 'email', 'password',
'experiences', 'headline')
def validate_email(self, value):
from validate_email_address import validate_email
if User.all_objects.filter(email=value.lower()).exists():
raise serializers.ValidationError('User with this email already exists.')
# if not validate_email(value.lower(), check_mx=True):
# raise serializers.ValidationError('It looks like you may have entered an incorrect email address.')
return value.lower()
def create(self, validated_data):
experiences = validated_data.pop('experiences')
password = validated_data.pop('password')
email = validated_data.pop('email')
user = User.objects.create(
username=email.lower(),
email=email.lower(),
role_id=1)
user.set_password(password)
user.save()
user_location = experiences.pop('user_location')
if hasattr(user, 'location'):
user.location.location = user_location
user.save()
else:
UserLocation.objects.create(user=user, location=user_location)
Experience.objects.create(user=user)
return user
Another serializes.py for Experiance
class ExperienceSerializer(serializers.HyperlinkedModelSerializer):
user_location = LocationField()
location = LocationField()
class Meta:
model = Experience
fields = ('id', 'company_name', 'company', 'description', 'location',
'title', 'start_date', 'end_date', 'is_current', 'user_location')
I want to Remove Validation from company_name, company, description, location, title, start_date, end_date, user_location
actually these fields are second page means after complete the first step users move on second step so second step fields are optional
class ExperienceSerializer(serializers.HyperlinkedModelSerializer):
user_location = LocationField()
location = LocationField()
class Meta:
model = Experience
fields = ('id', 'company_name', 'company', 'description', 'location',
'title', 'start_date', 'end_date', 'is_current', 'user_location')
def create(self, validated_data):
return Experience.objects.create(field_a='value', field_b='value')
in the above class, what should be do to remove validation of
"error_msg": {
"location": [
"Expected a dictionary of items but got type \"str\"."
],
"start_date": [
"Date has wrong format. Use one of these formats instead: YYYY[-MM[-DD]]."
],
"end_date": [
"Date has wrong format. Use one of these formats instead: YYYY[-MM[-DD]]."
],
"user_location": [
"Expected a dictionary of items but got type \"str\"."
]
}
Experience Model
class Experience(models.Model):
"""
"""
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='experiences')
company_name = models.CharField(max_length=200, db_index=True, blank=True)
company = models.ForeignKey('organisations.Organisation', null=True, blank=True, on_delete=models.SET_NULL)
description = models.TextField(null=True, blank=True)
location = models.ForeignKey('regions.Location', null=True, blank=True, on_delete=models.SET_NULL)
start_date = models.DateField(null=True, blank=True)
end_date = models.DateField(null=True, blank=True)
title = models.CharField(max_length=200, db_index=True, blank=True)
is_current = models.BooleanField(default=False)
is_associated = models.BooleanField(default=False)
created_at = models.DateTimeField(_('created at'), auto_now_add=True)
modified_at = models.DateTimeField(_('modified at'), auto_now=True)
class Meta:
db_table = 'experience'
verbose_name = _('experience')
verbose_name_plural = _('experiences')
ordering = ('-start_date',)
def __str__(self):
return getattr(self, 'title', '')
#property
def experience(self):
if self.end_date:
return (self.end_date - self.start_date).days
else:
return (datetime.datetime.now().date() - self.start_date).days
def get_formated_experience(self):
days = self.experience
total_months = round(days/30)
years = int(total_months/12)
months = round(((total_months/12)%1)*12)
year_txt = 'years' if years > 1 else 'year'
month_txt = 'months' if months > 1 else 'month'
return "%s %s %s %s" %(years, year_txt, months, month_txt)
Location Model
class Location(models.Model):
"""
"""
id = models.TextField(primary_key=True)
display_name = models.TextField(null=True, blank=True)
latitude = models.DecimalField(max_digits=15, decimal_places=10, null=True, blank=True)
longitude = models.DecimalField(max_digits=15, decimal_places=10, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
objects = LocationManager()
You are getting Two types of validation error according to snapshot.
Field is required
Expected a dictionary and got a string
The required field error occurs when you have set field as required in your model. You can change this by adding blank=True in your model for that field.
For second error, your serializer is expecting a dictionary and you are sending a string. You can remove this validation by writing your custom create method.
class ExperienceSerializer(serializers.HyperlinkedModelSerializer):
user_location = LocationField()
location = LocationField()
class Meta:
model = Experience
fields = ('id', 'company_name', 'company', 'description', 'location',
'title', 'start_date', 'end_date', 'is_current', 'user_location')
def create(self, validated_data):
# you create code for that models.
Your seriailzers will be like this
class ProfessionalRegistrationSerializer(serializers.HyperlinkedModelSerializer):
password = serializers.CharField(max_length=20, write_only=True)
experiences = ExperienceSerializer(required=False)
email = serializers.EmailField()
first_name = serializers.CharField(max_length=30)
last_name = serializers.CharField(max_length=30)
class Meta:
model = User
fields = ('url', 'id', 'first_name', 'last_name', 'email', 'password',
'experiences', 'headline')
def validate_email(self, value):
from validate_email_address import validate_email
if User.all_objects.filter(email=value.lower()).exists():
raise serializers.ValidationError('User with this email already exists.')
# if not validate_email(value.lower(), check_mx=True):
# raise serializers.ValidationError('It looks like you may have entered an incorrect email address.')
return value.lower()
def create(self, validated_data):
experiences = validated_data.get('experiences')
password = validated_data.get('password')
email = validated_data.get('email')
user = User.objects.create(
username=email.lower(),
email=email.lower(),
role_id=1)
user.set_password(password)
user.save()
user_location = experiences.get('user_location')
location_object = None
if user_location:
location_object, created = Location.objects.get_or_create(display_name=user_location.get('display_name'), latitude= user_location.get('latitude'), longitude=user_location.get('longitude'))
user_experience = Experience.objects.create(user=user, company_name=experiences.get('company_name'), location=location_object)
return user
class ExperienceSerializer(serializers.HyperlinkedModelSerializer):
user_location = LocationField()
location = LocationField()
class Meta:
model = Experience
fields = ('id', 'company_name', 'company', 'description', 'location',
'title', 'start_date', 'end_date', 'is_current', 'user_location')