Более эффективный и действенный кверисет?
У меня есть эти модели в моем проекте:
...
class User(AbstractBaseUser):
...
income = models.BigIntegerField()
...
class Credit(models.Model):
...
user = models.ForeignKey(User, on_delete=models.PROTECT)
cycle = models.CharField(choices=CYCLE_CHOICES, max_length=2)
amount = models.BigIntegerField()
...
Мне нужен набор запросов, который запрашивает базу данных для пользователя, чей доход больше $10,000, и у которого есть как минимум два (2) кредита, чье cycle равно cycle_credited и сумма $30,000.
В настоящее время у меня есть следующие наборы запросов:
...
user = get_object_or_404(User, id=id)
is_eligible = False
num_of_ten_k_credits = Credit.objects.filter(user=user, user__income__gt=10000, cycle=constants.cycle_credited, amount=30000).count()
if num_of_ten_k_credits >= 2:
is_eligible = True
Есть ли более эффективный и действенный способ сделать это? Например, однострочное решение с меньшим количеством вызовов БД?
Да, вы можете оптимизировать и сделать его более читабельным, добавив несколько изменений в существующую кодовую базу. Например, добавьте related_name в класс модели Credit
lass Credit(models.Model):
...
user = models.ForeignKey(User, on_delete=models.PROTECT, related_name="credits")
cycle = models.CharField(choices=CYCLE_CHOICES, max_length=2)
amount = models.BigIntegerField()
...
Вот как можно достичь желаемого результата, используя более оптимизированный и читабельный код
- Если вы находитесь внутри представления, имеющего запрос с пользователем
num_of_ten_k_credits = request.user.credits.filter(income__gt=10000,
cycle=constants.cycle_credited,
amount=30000,
)
if num_of_ten_k_credits >= 2:
is_eligible = True
- Если вы не в представлениях и у вас нет
request.user, то сделайте это следующим образом
user = get_object_or_404(User, id=id)
num_of_ten_k_credits = user.credits.filter(income__gt=10000,
cycle=constants.cycle_credited,
amount=30000,
)
if num_of_ten_k_credits >= 2:
is_eligible = True
В обоих случаях я старался избегать __, которые по своей природе являются соединениями и делают запросы медленными.