django-ninja icon indicating copy to clipboard operation
django-ninja copied to clipboard

Is there any document or helps to migrate from drf to django-ninja?

Open quroom opened this issue 2 years ago • 9 comments

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?

quroom avatar Jul 01 '22 00:07 quroom

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 avatar Jul 08 '22 20:07 ihelmer07

@ihelmer07

Could you show some example where you write custom functions ?

vitalik avatar Jul 09 '22 07:07 vitalik

@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 avatar Jul 15 '22 03:07 ihelmer07

@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 avatar Jul 15 '22 07:07 vitalik

@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

ihelmer07 avatar Jul 15 '22 11:07 ihelmer07

@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 avatar Jul 20 '22 13:07 ihelmer07

@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.

quroom avatar Jul 21 '22 23:07 quroom

Hi @ihelmer07 @quroom

so there is a bug in Manytomany fields - now it should work in pyalodas ( fixed in version 0.19.1)

vitalik avatar Jul 22 '22 08:07 vitalik

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.

quroom avatar Jul 22 '22 08:07 quroom