Opened 4 months ago

Last modified 5 days ago

#36888 assigned Bug

acreate method doesn't call asave

Reported by: Mateusz Szymanowski Owned by: Mateusz Szymanowski
Component: Database layer (models, ORM) Version: 6.0
Severity: Normal Keywords: acreate asave async
Cc: Mateusz Szymanowski Triage Stage: Someday/Maybe
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

acreate doesn't call asave method.

When you use async Django methods and you want to add custom logic in asave method, when you create your object with acreate, it doesn't call your asave method.

class SimpleModel(models.Model):
    field = models.IntegerField()

    async def asave(self, *args, **kwargs):
        self.field += 1
        await super().asave(*args, **kwargs)

obj = await SimpleModel.objects.acreate(field=4)
obj.field # returns 4, should be 5

When you run create, it calls save().

Change History (11)

comment:1 by Mateusz Szymanowski, 4 months ago

Has patch: set

comment:2 by Natalia Bidart, 4 months ago

Easy pickings: unset
Keywords: async added
Triage Stage: UnreviewedAccepted

Thank you Mateusz for your report! Great catch.

comment:3 by Mariusz Felisiak, 4 months ago

Patch needs improvement: set

comment:4 by Mariusz Felisiak, 4 months ago

Owner: changed from @… to Mateusz Szymanowski

comment:5 by Jericho Serrano, 3 months ago

Owner: changed from Mateusz Szymanowski to Jericho Serrano

comment:6 by Jericho Serrano, 3 months ago

Needs tests: set
Patch needs improvement: unset

comment:8 by Natalia Bidart, 3 months ago

Needs tests: unset
Owner: changed from Jericho Serrano to Mateusz Szymanowski

Restoring the previous owner since the PR is needing a re-review, but owner did not update the ticket flags I think.

comment:9 by Jericho Serrano, 3 months ago

Hello Natalia, my bad; I thought this ticket was inactive. I lately realized the owner's PR is still ongoing, and there was no activity here in the track ticket.

comment:10 by Jacob Walls, 3 months ago

Patch needs improvement: set

comment:11 by Jacob Walls, 5 days ago

Triage Stage: AcceptedSomeday/Maybe

Before, acreate() had a sync_to_async() right off the bat:

     async def acreate(self, **kwargs):
        return await sync_to_async(self.create)(**kwargs)

Attempts in the PRs to remove that sync_to_async() stalled on the fact that GenericForeignKeyDescriptor.__set__ accesses the database (see generic_relations.tests.GenericRelationsTests.test_aadd).

If we're just shuffling around *where* the sync_to_async lies, then we're not accomplishing very much, as pointed out in the reviews. I posted a sketch of an async interface for Model instantiation.

I think we need both that as well as an async implementation of ContentType methods (aget_content_type() etc.) before we can advance this.

If someone can confirm the general direction, we can open separate tickets for those.

Version 0, edited 5 days ago by Jacob Walls (next)
Note: See TracTickets for help on using tickets.
Back to Top