Giter Site home page Giter Site logo

Multi ForeignKey not working about ormar HOT 3 CLOSED

collerek avatar collerek commented on May 18, 2024
Multi ForeignKey not working

from ormar.

Comments (3)

collerek avatar collerek commented on May 18, 2024

Ok, so this is how you go from parent model to child model in ForeigKey relation:

# you need to go through QuerySet and select related model 'chargingpads' and select all()
# will get you a list of stations (and you created only one) so yours is at index 0
# note that you CAN use instance here (charging_station.objects...) but better be explicit as this can be changed in future releases
station = await ChargingStationOrm.objects.select_related('chargingpads').all()
assert len(station[0].chargingpads) == 4

# the same but get by pk (or any other filter combination that will return one row) so no list and no need for index
# note that if you do not provide filter parameters for now the query is limited to 2 rows - plan to change that in the future
# so if you provide just get() at the end there will be only 2 pads - it's a feature not a bug as empty get should not be issued with select_related
station2 = await ChargingStationOrm.objects.select_related('chargingpads').get(pk=1)
assert len(station2.chargingpads) == 4

This is actually the only not yet implemented load (you can load child from parent: so charging_pad.charging_station.load() and child of ManyToMany with Model.many_to_many_name.all()).

You can find some explanation and discussion in #27.
Probably it will be added but still this produces additional query and this is probably not something you want performance wide -> select related composes a (sometimes complex) join in only one db query -> nested models are later extracted from result in python.

from ormar.

collerek avatar collerek commented on May 18, 2024

Oh and if you want the other way around use:

# only pads
pads = ChargingPad.object.all()
assert len(pads) == 4

# only pads and only pk field -> will complain if you try to exclude required fields
pads = ChargingPad.object.fields("id").all()
assert len(pads) == 4

# with station
pads = ChargingPad.object.select_related("charging_station").all()
assert len(pads) == 4

Note that ormar never returns you raw data. So even if you limit your query to one field (pk as it cannot be excluded - pk is always returned - note that regardless of the real name you can always set it and get it by pk alias) you will get a model with only one field populated (rest will be None). That's why if you want to exclude fields from result those fields needs to be nullable=True as otherwise pydantic will raise ValidationError. (more on this in fields() and exclude_fields() docs in queries)

So even in the first query above you can still go pads[0].charging_station.load() even if you did not provide select_related(), as the foreignkey database column is filled and ormar provides you with nested CharingStationOrm model with pk only populated (this is a special case where only pk can be set and no ValidationError is raised. If you explicitly set select_related stating that you want a nested model returned from a database and try to exclude required fields it will complain).

If you think that the documentation is not clear in this regard let me know. (Or you can issue a PR - it's always easier to start contributing with the docs). If that answers your question please close the issue :)

from ormar.

EspenAlbert avatar EspenAlbert commented on May 18, 2024

Awesome. Thank you so much for the detailed how-to :)

I feel encouraged to contribute. Let's see what happens ;)

from ormar.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.