django-ninja
django-ninja copied to clipboard
Is there any document or helps to migrate from drf to django-ninja?
It is not related to issue. I am really thanksful to the founder of django-ninja I was shocked it's really fast and easy and simplified comparing DRF So I choosed to use django-ninja + ninja-extra to my new project. But I already made some projects with drf so nowadays I want to migrate all project from DRF to django-ninja , improving performance also simplify code structures.
Is there any tutorials or examples to acheive that? or supposed to make it?
I don't know of any documentation however question - The biggest gap I've encountered with Django Ninja is the ability to POST/PUT m2m fields, which we do a lot of.
It looks that I have to custom write the functions to handle that which is a HUGE pain.
Do you know of how to deal with the POST/PUT of M2M fields?
@ihelmer07
Could you show some example where you write custom functions ?
@vitalik
Disclaimer - I may be missing something fundamental about django-ninja so please let me know if I'm wrong.
I've created a github example repo that shows the issue click here
For models with M2M relations, coming from DRF - one can post payloads such as {"city_id": 1, "people": [2, 3, 4], "name": "Party People"}
where the ints
are the id
of the respective models and they will successfully create that object. Django-ninja does not do this and throws an AttributeError: 'int' object has no attribute 'pk'
.
Please look at the example repo that shows an apples to apples comparison for POSTing. I can update it with PUT if needed.
@ihelmer07
I assume you talke about this method:
@api.post("/order")
def create_order(request, payload: OrderPostSchema):
"""
gives "AttributeError: 'int' object has no attribute 'pk'" when POSTing a payload that looks like:
d = {"city_id": 1, "name": [2, 3, 4]}
when those pks are known to exist.
"""
obj = Order.objects.create(**payload.dict())
return {"id": obj.id}
this is just the way django works - you cannot pass the integers for m2m - need to query it:
@api.post("/order")
def create_order(request, payload: OrderPostSchema):
data = paylaod.dict()
names = data.pop('name')
obj = Order.objects.create(**data)
obj.name.add(*names)
return {"id": obj.id}
@vitalik - what you say makes sense however it is still failing with AttributedError: 'int' object has no attribute 'pk'
I've updated the example repo per the above and tests still fail as well as manually trying it.
Traceback:
'int' object has no attribute 'pk'
Traceback (most recent call last):
File "c:\users\isaac\documents\sa\dj-example\venv\lib\site-packages\ninja\operation.py", line 98, in run
values = self._get_values(request, kw, temporal_response)
File "c:\users\isaac\documents\sa\dj-example\venv\lib\site-packages\ninja\operation.py", line 212, in _get_values
data = model.resolve(request, self.api, path_params)
File "c:\users\isaac\documents\sa\dj-example\venv\lib\site-packages\ninja\params_models.py", line 57, in resolve
return cls(**data)
File "pydantic\main.py", line 339, in pydantic.main.BaseModel.__init__
File "pydantic\main.py", line 1038, in pydantic.main.validate_model
File "pydantic\fields.py", line 857, in pydantic.fields.ModelField.validate
File "pydantic\fields.py", line 1074, in pydantic.fields.ModelField._validate_singleton
File "pydantic\fields.py", line 1121, in pydantic.fields.ModelField._apply_validators
File "pydantic\class_validators.py", line 313, in pydantic.class_validators._generic_validator_basic.lambda12
File "pydantic\main.py", line 686, in pydantic.main.BaseModel.validate
File "pydantic\main.py", line 339, in pydantic.main.BaseModel.__init__
File "pydantic\main.py", line 1038, in pydantic.main.validate_model
File "pydantic\fields.py", line 868, in pydantic.fields.ModelField.validate
File "pydantic\fields.py", line 901, in pydantic.fields.ModelField._validate_sequence_like
File "pydantic\fields.py", line 1067, in pydantic.fields.ModelField._validate_singleton
File "pydantic\fields.py", line 857, in pydantic.fields.ModelField.validate
File "pydantic\fields.py", line 1074, in pydantic.fields.ModelField._validate_singleton
File "pydantic\fields.py", line 1121, in pydantic.fields.ModelField._apply_validators
File "pydantic\class_validators.py", line 313, in pydantic.class_validators._generic_validator_basic.lambda12
File "c:\users\isaac\documents\sa\dj-example\venv\lib\site-packages\ninja\orm\fields.py", line 87, in validate
return v.pk
AttributeError: 'int' object has no attribute 'pk'
Internal Server Error: /api/order
@vitalik friendly ping. This is the 1 thing that prevents my team from transitioning to 100% django-ninja so any help is very appreciated!
@ihelmer07 But if there is some problem with ModelSchema. I tested with your code but somehow M2M field is not passed as object. it is just id. That's why it happened. object has pk but integer id doesn't include pk.
Now It's not real solution, you can declare each schema. But It can be more complex than using ModelSchema. But I am sure it can fix your problem.
https://django-ninja.rest-framework.com/tutorial/response-schema/
You can set your own InSchema to avoid error.
Hi @ihelmer07 @quroom
so there is a bug in Manytomany fields - now it should work in pyalodas ( fixed in version 0.19.1)
Hi @ihelmer07 @quroom
so there is a bug in Manytomany fields - now it should work in pyalodas ( fixed in version 0.19.1)
Someday when I more understand django ninja, I hope to make pr.
I am really thanksful your great work.