tortoise / tortoise/tortoise-orm

ManyToMany relation with extra field

Open
#612 3 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Python
Stars
5.6k
Forks
516
Avg merge
2d 21h
Merged PRs (30d)
9

Description

Hello,

I would like to know if it’s possible to have a ManyToMany relationship with an extra filed.
I have a drug model that may contains multiple molecules models.
I would like to display this relation with an additional field: quantity.
I need to display the quantity at the same level as the molecule's information.

This is my endpoint :

@router.get('/', response_model=List[DrugResponse])
async def drugs():
    """Returns a list of drugs. """
    
    return await DrugResponse.from_queryset(Drug.all())

This is my models :

class Drug(Model):
    id = fields.IntField(pk=True)
    label = fields.CharField(max_length=128, null=False)

    class Meta:
        table = "drugs"


class DrugMolecule(Model):
    drug = fields.ForeignKeyField("models.Drug", related_name='molecules', null=False)
    molecule = fields.ForeignKeyField("models.Molecule", related_name=False, null=False)
    quantity = fields.FloatField(null=True)

    class Meta:
        table = 'drug_molecule'


class Molecule(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=128, null=False)

    class Meta:
        table = 'molecules'

    class PydanticMeta:
        exclude = ["administration_context"]

I would like that my endpoint return an object structured like this :

[
  {
    "id": 1,
    "label": "ADVIL 200mg, comprimé enrobé",
    "molecules": [
      {
        "id": 1, // molecule_id
        "name": "Ibuprofen",
        "quantity": 100 // extra field quantity
      },
      {
        "id": 2, // molecule_id
        "name": "Hydroxychloroquine",
        "quantity": 100 // extra field quantity
      }
    ]
  }
]

But for now, my endpoint return an object like this :

[
  {
    "id": 1,
    "label": "ADVIL 200mg, comprimé enrobé",
    "molecules": [
      {
        "id": 1,
        "molecule": {
          "id": 1,
          "name": "Ibuprofen"
        },
        "quantity": 100 // extra field quantity
      },
      {
        "id": 2,
        "molecule": {
          "id": 2,
          "name": "Hydroxychloroquine"
        },
        "quantity": 100 // extra field quantity
      }
    ]
  }
] 

Could you please explain me how I can get the well structured return please ?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Drug, DrugMolecule, and Molecule models and the drugs endpoint shown in the issue; inspect how DrugResponse serializes the reverse relation and nested molecule. Compare that behavior with the requested flattened molecules JSON, including quantity. Done means the endpoint returns the requested shape without losing the extra field.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, database
Issue type
Documentation
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.