Использование функции класса в качестве переменной в Django
У меня есть этот файл models.py в моем проекте Django
from django.db import models
from django.urls import reverse
from django.utils.timezone import now
class Campaign(models.Model):
class Meta:
db_table = 'campaign'
campaign_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255, default='')
topic = models.CharField(max_length=255, default='')
sender = models.CharField(max_length=255, default='')
start_date = models.DateTimeField(default=now)
is_active = models.BooleanField(default=False)
draft = models.BooleanField(default=True)
content = models.TextField(default='')
footer = models.CharField(max_length=255, default='')
unsubscribe_message = models.CharField(max_length=255, default='')
@property
def get_completion_percent(self):
return 70
И я пытаюсь использовать функцию get_completion_percent в моем views.py в качестве фильтра прямо здесь
def finished_ads_view(request):
queryset = Campaign.objects.filter(get_completion_percent=100)
context = {
'object_list': queryset,
}
return render(request, 'campaigns_in_progress.html', context)
Но ошибка, которую я получаю, выглядит следующим образом:
FieldError at /finished_campaigns/ Невозможно преобразовать ключевое слово 'get_completion_percent' в поле. Варианты: campaign_id, content, draft, footer, is_active, name, sender, start_date, topic, unsubscribe_message
Может ли кто-нибудь помочь мне заставить это работать?
Вы не можете фильтровать свойство.
Если вам нужен процент, вы можете использовать .annotate() и отфильтровать поле.
Campaign.objects.annotate(percentage=70).filter(percentage=100)
Если вам нужно выполнить операцию над полями одной записи, вы можете получить значения с помощью выражения F()
Я попытаюсь дать решение. Оно не проверено, поэтому вы должны попробовать его и сообщить мне, если оно работает. Я пытаюсь понять, что является вашей конечной целью, и, насколько я понимаю, это отобразить что-то, если процент завершения достигнет 100. Я бы добавил еще одну модель, например, такую:
class Percentage(models.Model):
campaign= models.ForeignKey(
Campaign, on_delete=models.CASCADE, null=True, blank=True)
percentage= models.IntegerField(default=0, blank=True, null=True) #I don't know if you need integer or float
Теперь, используя этот внешний ключ, вы можете выполнить вычисления (в представлении, я полагаю), чтобы получить процент. Примером может быть:
from django.db.models import Sum # remember this import
def finished_ads_view(request, pk):
campaign = Campaign.objects.filter(campaign_id=pk)
percentages = Percentage.objects.filter(campaign=campaign).aggregate(Sum(percentage))
if percentages == 100:
context = {
'object_list': percentages,
} #this context is idented inside the if statement
else:
percentages = 'Not completed' # or whatever you want display if the percentage is not 100
context = {
'object_list': percentages,
}
return render(request, 'campaigns_in_progress.html', context)
Это просто попытка, дайте мне знать, если это сработает. Я не тестировал код, так что могут быть ошибки, но я бы сделал что-то вроде этого