Home > Blockchain >  Django Async View - Model __str__
Django Async View - Model __str__

Time:08-08

I'm trying to convert my existing Django 4.1 app to async due to performance reasons. It's more of a struggle than I initially anticipated.

Below is some test code:

async def diagrams(request):

    tests = await sync_to_async(list)(Test.objects.filter(name='Test 1'))
    print(tests)

    return render(request, 'analyticsApp/test.html')


class Test2(models.Model):
    name = models.CharField(max_length=50, default='', blank=True)

    def __str__(self):
        return self.name


class Test(models.Model):
    name = models.CharField(max_length=50, default='', blank=True)
    testForeignKey = models.ForeignKey(Test2, editable=True, on_delete=models.CASCADE, blank=True, null=True)

    def __str__(self):
        # Need to get foreign key here in async way but this function cannot be async ??
        return self.name   '_'   self.testForeignKey.name

So I kind of figured out how to "filter" objects using async_to_async. However, a problem that I'm struggling to solve is using __str__ in a Model. All of my models use __str__ to give accurate string depcitions of the model. It seems like this cannot be done ? I tried to convert def __str__ to async def __str__ but django is not awaiting this when it is being called so it causes problems.

Any idea how to handle this ?

CodePudding user response:

Probably the async don't increase your performance.

In your code you work don't correct with async. Str should work with existing data, without ask to database. Therefore you should receive needed data before instance init.

In your case you can made:

obj = Test.objects.select_related("testForeignKey").get(**something)

Also you can use defer/only. The query works async, after that you get your Str(object) normally.

CodePudding user response:

I have't used much the async support but as a work around you can use a select_related

async def diagrams(request):

    tests = await sync_to_async(list)(
        Test.objects.filter(name='Test 1')
            .select_related('testForeignKey')
    )
    print(tests)

    return render(request, 'analyticsApp/test.html')
  • Related