У объекта Django 'IntegerField' нет атрибута 'get_internal_type'
Ребята, я пытался использовать ExpressionWrapper в django и получить выходное поле как IntegerField(), я не знаю, где я ошибаюсь
Импорт
# Imports from django.core
from attr import fields
from django.db import models
from django.db.models import DecimalField, IntegerField, Avg,Subquery,OuterRef, Q, Sum, F, ExpressionWrapper
from django.db.models.functions import ExtractYear
from django.contrib.auth.models import User
from django.forms import DateField, DecimalField, IntegerField
from django.shortcuts import get_object_or_404
from django.utils import timezone
# Imports froms apps
from shop.models import CartItem, Order, OrderItem, Product, Review
from wallets.models import Transaction, Wallet
Это часть кода метода модели
Profile.objects.filter(
id__in = Wallet.objects.filter(
id__in=purchases_made_for_on_store_products.values('wallet')
).values('user')
).values('dob').annotate(
age = ExpressionWrapper(ExtractYear(dt.today()) - ExtractYear(F('dob')),
output_field=IntegerField()))
)
Я ожидал, что код будет вычислять возраст каждого пользователя и временно хранить его в поле "возраст". Это позволило бы мне аннотировать его и в дальнейшем использовать для фильтрации.
Вы дважды импортируете IntegerField, переопределяя импорт поля модели:
from django.db.models import DecimalField, IntegerField,...
...
from django.forms import ..., IntegerField
Убедитесь, что вы используете поле модели в наборе запросов, например, задав полю формы другое имя:
from django.forms import IntegerField as IntegerFormField
Вероятно, вам даже не нужна обертка выражения, вы можете извлечь год и год дня рождения:
Profile.objects.filter(
id__in=Wallet.objects.filter(
id__in=purchases_made_for_on_store_products.values('wallet')
).values('user')
).values('dob').annotate(age=dt.today().year - ExtractYear('dob'))
But now the bad news, this is not the age: you are determining the year minus the year of birth. So if someone is born in 1993 for example, you assume that that person will always be 31 years old, even if he is born on October 14th for example, and thus it takes some extra days. You will need to compare the day of birth as well thus.
На самом деле, у объекта 'IntegerField' нет атрибута 'get_internal_type', обычно это происходит, когда путают поля модели и поля формы. В вашем коде вы импортировали и модель IntegerField, и форму IntegerField. Вы должны использовать модель IntegerField для ExpressionWrapper.
from django.db import models
from django.db.models import DecimalField, IntegerField, Avg, Subquery, OuterRef, Q, Sum, F, ExpressionWrapper
from django.db.models.functions import ExtractYear
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from django.utils import timezone
# Imports from apps
from shop.models import CartItem, Order, OrderItem, Product, Review
from wallets.models import Transaction, Wallet
# Import datetime to get the current year
from datetime import datetime
# Profile model method example
Profile.objects.filter(
id__in=Wallet.objects.filter(
id__in=purchases_made_for_on_store_products.values('wallet')
).values('user')
).values('dob').annotate(
age=ExpressionWrapper(
datetime.now().year - ExtractYear(F('dob')),
output_field=IntegerField()
)
)