I am new to this django-rest-framework, my problem is how am I going to insert a data with one-to-one relationship in the views.py. I can do the normal way of inserting data like the one below,
def post(self, request,format=None):
p = Person()
p.firstname = "John"
p.middlename = "K"
p.lastname = "Rambo"
p.save()
e = Employee()
e.code = "emp-002"
e.person_id = p.id
e.save()
I cannot do the approach above because I want to learn more about DRF.
To give you more idea please see below:
I have this model
class Person(models.Model):
firstname = models.CharField(max_length=150, default="")
middlename = models.CharField(max_length=150, default="")
lastname = models.CharField(max_length=150, default="")
class Employee(models.Model):
person = models.OneToOneField(Person, on_delete=models.CASCADE,primary_key=True)
code = models.CharField(max_length=100, default="")
I have this serializer
class PersonSer(serializers.ModelSerializer):
class Meta:
model = Person
fields = (
'id',
'firstname',
'middlename',
'lastname',)
class EmployeeSer(serializers.ModelSerializer):
person = PersonSer()
class Meta:
model = Employee
fields = ('code','person')
I have this view
class SaveData(APIView):
@transaction.atomic
def post(self,request, format=None):
p = PersonSer(data=request.data)
if p.is_valid():
p.save()
request.data['person'] = p.data['id']
request.data['code'] = "Emp-"+str(p.data['id'])
"""
I expect request.data now equal to
{
'person' : 102, # we assume the newly created person id == 102
'code' : 'Emp-102',
'firstname' : 'John',
'middlename' : 'K.',
'lastname' : 'Rambo'
}
"""
es = EmployeeSer(data=request.data)
if es.is_valid():
es.save()
else:
print(es.errors) # {'person': [ErrorDetail(string='This field is required.', code='required')]}
"""
I also tried this,
es = EmployeeSer(data={'person' : p.data, 'code' : 'Sample code'})
if es.is_valid():
es.save()
else:
print(es.errors) #{'person': {'fullname': [ErrorDetail(string='This field may not be blank.',code='blank')], ]}}
"""
return Response({'message':'okay'})
The request.data is a formData, the value is
{
'firstname' : 'John',
'middlename' : 'K.',
'lastname' : 'Rambo'
}
You can override the create method of the PersonSer to achieve this.
class PersonSer(serializers.ModelSerializer):
...
def create(self, validated_data):
person = Person.objects.create(**validated_data)
Employee.objects.create(person=person, code=f"Emp-{person.id}")
return person
And you can simplify your view to:
...
@transaction.atomic
def post(self,request, format=None):
p = PersonSer(data=request.data)
p.is_valid(raise_exception=True)
p.save()
return Response({'message':'okay'})
...
raise_expection=True
will cause serializer to raise ValidationError
exception if there are validation errors.
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.