0

Which method should I use in jango 2.1 for the create method to add new objects that supports also the creation of nested fields (ForeignKey relation). I always get the Error Message:

AssertionError at /client/create/ The .create() method does not support writable nested fields by default.

User Model

class User(models.Model):
gender = models.CharField(max_length=10, choices=GENDER)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
position = models.CharField(max_length=50)
birthday = models.DateField(auto_created=False)
email = models.EmailField(max_length=50)
phone = models.CharField(max_length=15)
password = models.CharField(max_length=100)

def __str__(self):
    return f"{self.first_name} {self.last_name} {self.position} {self.email} {self.phone} {self.password}"

Company Model

class Company(models.Model):
company_name = models.CharField(max_length=50, blank=False)
address = models.CharField(max_length=50, blank=False)
zip = models.IntegerField(blank=False)
city = models.CharField(max_length=50, blank=False)
email = models.EmailField(max_length=50, blank=False)

def __str__(self):
    return f"{self.company_name} {self.address} {self.zip} {self.city}"

Client Company

class ClientCompany(models.Model):
client = models.ForeignKey(Company, on_delete=models.PROTECT)
contact_person = models.ForeignKey(User, on_delete=models.PROTECT)
status = models.CharField(max_length=15, choices=STATUS, default='Aktiv')

def __str__(self):
    return f"{self.client} {self.contact_person} {self.status}"

User Serializer

class UserSerializer(serializers.ModelSerializer):
class Meta:
    model = User
    fields = '__all__'

ClientCompanySerializer

class ClientCompanySerializer(serializers.ModelSerializer):
    client = CompanySerializer(many=False, read_only=False)
    contact_person = ClientUserSerializer(many=False, read_only=True)

    class Meta:
        model = ClientCompany
        fields = '__all__'

UserUrls

    urlpatterns = [
path('update/id<int:id>', UpdateUserByID.as_view(), name='user-update'),
path('id/<int:id>', GetUserByID.as_view(), name='user-id'),
path('create', CreateUser.as_view(), name='create-user'),
path('delete/id/<int:id>', DeleteUserByID.as_view(), name='delete-user'),

]

CompanyUrls

urlpatterns = [
path('update/id<int:id>', CompanyUpdateByID.as_view(), name='company-udpate'),
path('id/<int:id>', CompanyById.as_view(), name='company-id'),
path('create/', CreateCompany.as_view(), name='company-create'),
path('delete/id/<int:id>', DeleteCompanyByID.as_view(), name='company-delete')

]

CompanyView

class CreateCompany(generics.CreateAPIView):
queryset = Company.objects.all()
serializer_class = CompanySerializer

My goal is to create a new company (and the related fk 'contact_person') in the url /company/create/

Is there a way to create the related 'contact_person' within the 'ClientCompanySerializer' or should I use a different approach.

4
  • Please, share your models and serializers for Company and User. Commented Feb 13, 2019 at 14:25
  • Hi Hugo, I have added the company and user serializer + model, thank you! Commented Feb 13, 2019 at 15:08
  • How are you sending the data for contact_person? I think I am going to need your urls.py and your related views too. Commented Feb 13, 2019 at 15:13
  • I have added the related urls and views. Commented Feb 13, 2019 at 15:21

1 Answer 1

1

you need to override the default create and update methods in serializers like below:

first remove read_only=True from contact_person

def create(self, validated_data):
client = validated_data.pop('client')
contact_person = validated_data.pop('contact_person')
client_instance = Company.object.create(**client)
contact_person_instance = User.object.create(**contact_person)
return ClientCompany.objects.create(client=client_instance,contact_person=contact_person_instance , **validated_data)

also, implement a similar method for update

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot, it's working properly fine as it is supposed to! :)
@Jetmir please mark the answer as accepted, so that others can also be sure that it is a working solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.