AttributeError с пользователем в приложении djangoPython

Программы на Python
Ответить
Anonymous
 AttributeError с пользователем в приложении django

Сообщение Anonymous »

Я делаю приложение для клиники. Я нахожусь в финансовом разделе своего приложения. Я хочу получать доход от встреч. Когда я приступил к тестированию этой конечной точки в почтальоне, я получил следующую ошибку: AttributeError: Got AttributeError при попытке получить значение для поля user в сериализаторе UserInfoSerializer.
Поле сериализатора может быть названо неправильно и не соответствует ни одному атрибуту или ключу экземпляра User.
Исходный текст исключения был следующим: Объект «Пользователь» не имеет атрибута «пользователь».
Я являюсь отправляю вам свои файлы, чтобы вы могли мне помочь, так как у меня была эта ошибка в течение нескольких дней, и я не мог ее решить.
userinfo/models.py

Код: Выделить всё

from django.db import models
from django.contrib.auth.models import User

class UserInfo(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="userInfo")
address = models.CharField(max_length=255, blank=True, null=True)
phone = models.CharField(max_length=15, blank=True, null=True)
fecha_nacimiento = models.DateField(blank=True, null=True)
dni = models.CharField(max_length=10, blank=True, null=True)
postal_code = models.CharField(max_length=6, blank=True, null=True)
city = models.CharField(max_length=200, blank=True, null=True)
country = models.CharField(max_length=100, blank=True, null=True)
segundo_apellido = models.CharField(max_length=200, blank=True)

def __str__(self):
return f"Información de {self.user.username}"`
Мои finanzas/models.py:

Код: Выделить всё

from django.db import models
from citas.models import Citas
from userinfo.models import UserInfo

class Transaccion(models.Model):
INGRESO = 'INGRESO'
GASTO = 'GASTO'
INGRESO_COTIZADO = 'INGRESO_COTIZADO'

TIPO_CHOICES = [
(INGRESO, 'Ingreso'),
(GASTO, 'Gasto'),
(INGRESO_COTIZADO, 'Ingreso_Cotizado')
]

tipo = models.CharField(
max_length=100,
choices=TIPO_CHOICES,
default=INGRESO,
)
monto = models.DecimalField(max_digits=10, decimal_places=2)
descripcion = models.TextField()
fecha = models.DateTimeField(auto_now_add=True)
cita = models.ForeignKey(Citas, on_delete=models.CASCADE)  # Relacionado con la cita
user = models.ForeignKey(UserInfo, on_delete=models.CASCADE)  # Relacionado con el usuario que cotiza
url = models.URLField(null=True, blank=True)

def __str__(self):
return f"Transacción de {self.tipo} por {self.monto} para la cita {self.cita}"

class ConfiguracionFinanzas(models.Model):
precio_cita_base = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name="Precio base de la cita")
ultima_actualizacion = models.DateTimeField(auto_now=True)

def __str__(self):
return f"Configuración de Finanzas (Precio Cita:  {self.precio_cita_base})"
< /code>
my views.py:
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from finanzas.models import Transaccion, ConfiguracionFinanzas
from citas.models import Citas
from django.db.models import Sum
from .serializers import TransaccionSerializer, ConfiguracionFinanzasSerializer
from rest_framework.exceptions import NotFound
from datetime import datetime, timedelta
from django.utils import timezone

def obtener_transacciones_por_periodo(filtro, usuario_info):
hoy = timezone.now()
transacciones = Transaccion.objects.filter(usuario=usuario_info)

if filtro == 'mensual':
inicio_mes = hoy.replace(day=1)
transacciones = transacciones.filter(fecha__gte=inicio_mes)
elif filtro == 'trimestral':
inicio_trimestre = hoy - timedelta(days=90)
transacciones = transacciones.filter(fecha__gte=inicio_trimestre)
elif filtro == 'anual':
inicio_anio = hoy.replace(month=1, day=1)
transacciones = transacciones.filter(fecha__gte=inicio_anio)

return transacciones

def obtener_balance_por_periodo(tipo, filtro, usuario_info):
hoy = timezone.now()
transacciones = Transaccion.objects.filter(tipo=tipo, usuario=usuario_info)

if filtro == 'mensual':
inicio_mes = hoy.replace(day=1)
transacciones = transacciones.filter(fecha__gte=inicio_mes)
elif filtro == 'trimestral':
inicio_trimestre = hoy - timedelta(days=90)
transacciones = transacciones.filter(fecha__gte=inicio_trimestre)
elif filtro == 'anual':
inicio_anio = hoy.replace(month=1, day=1)
transacciones = transacciones.filter(fecha__gte=inicio_anio)

return transacciones.aggregate(Sum('monto'))['monto__sum'] or 0

class ListarGananciasCitasView(APIView):
"""
Listar las transacciones de ganancias por citas.
"""
def get(self, request):
filtro = request.query_params.get('filtro', 'total')
usuario_info = request.user.userInfo
transacciones = obtener_transacciones_por_periodo(filtro, usuario_info)

serializer = TransaccionSerializer(transacciones, many=True)
return Response(serializer.data)

class CrearGananciasCitasView(APIView):
"""
Vista para crear una transacción de tipo 'Ingreso' o 'Gasto'.
Asocia la transacción a una cita y al usuario que la cotiza.
"""
def post(self, request, cita_id):
if not request.user.is_authenticated:
return Response({"detail": "Usuario no autenticado."}, status=status.HTTP_401_UNAUTHORIZED)

try:
cita = Citas.objects.get(id=cita_id)
except Citas.DoesNotExist:
raise NotFound("Cita no encontrada.")

if cita.user != request.user:
return Response({"detail": "No puedes modificar una cita de otro usuario."}, status=status.HTTP_403_FORBIDDEN)

monto = request.data.get('monto')
descripcion = request.data.get('descripcion')
if monto is None or descripcion is None:
return Response({"detail": "Se requieren los campos 'monto' y 'descripcion'."}, status=status.HTTP_400_BAD_REQUEST)

tipo = 'INGRESO' if not cita.cotizada else 'INGRESO_COTIZADO'

usuario_info = getattr(request.user, 'userInfo', None)
if usuario_info is None:
return Response({"detail": "Información del usuario no encontrada."}, status=status.HTTP_404_NOT_FOUND)
transaccion = Transaccion.objects.create(
tipo=tipo,
monto=monto,
descripcion=descripcion,
cita=cita,
user=usuario_info,
)

serializer = TransaccionSerializer(transaccion)
return Response(serializer.data, status=status.HTTP_201_CREATED)

class MarcarCitaCotizadaView(APIView):
"""
Vista para marcar una cita como cotizada
"""
def post(self, request, cita_id):
if not request.user.is_authenticated:
return Response({"detail": "Usuario no autenticado."}, status=status.HTTP_401_UNAUTHORIZED)

try:
cita = Citas.objects.get(id=cita_id)
except Citas.DoesNotExist:
raise NotFound("Cita no encontrada.")

if cita.usuario != request.user.userInfo:
return Response({"detail":  "No puedes modificar una cita de otro usuario."}, status=status.HTTP_403_FORBIDDEN)

cita.cotizada = True
cita.save()

return Response({"message": "Cita marcada como cotizada"}, status=status.HTTP_200_OK)

class CrearGastoView(APIView):
"""
Vista para crear un gasto independiente de las citas.
"""
def post(self, request):
if not request.user.is_authenticated:
return Response({"detail": "Usuario no autenticado."}, status=status.HTTP_401_UNAUTHORIZED)

monto = request.data.get('monto')
descripcion = request.data.get('descripcion')
if monto is None or descripcion is None:
return Response({"detail": "Se requieren los campos 'monto' y 'descripcion'."}, status=status.HTTP_400_BAD_REQUEST)

tipo = "GASTO"
url = request.data.get('url', None)

usuario_info = request.user.userInfo
gasto = Transaccion.objects.create(
tipo=tipo,
monto=monto,
descripcion=descripcion,
usuario=usuario_info,
url=url
)

serializer = TransaccionSerializer(gasto)
return Response(serializer.data, status=status.HTTP_201_CREATED)

class ListarGastosView(APIView):
"""
Listar los gastos del usuario autenticado
"""
def get(self, request):
filtro = request.query_params.get('filtro', 'total')
usuario_info = request.user.userInfo
gastos = obtener_transacciones_por_periodo(filtro, usuario_info)

serializer = TransaccionSerializer(gastos, many=True)
return Response(serializer.data)

class ConfiguracionFinanzasView(APIView):
"""
Obtener y actualizar la configuración de finanzas.
"""
def get(self, request):
configuracion = ConfiguracionFinanzas.objects.first()
if not configuracion:
configuracion = ConfiguracionFinanzas.objects.create(precio_cita_base=0)
serializer = ConfiguracionFinanzasSerializer(configuracion)
return Response(serializer.data)

def put(self, request):
configuracion = ConfiguracionFinanzas.objects.first()
if not configuracion:
configuracion = ConfiguracionFinanzas.objects.create(precio_cita_base=0)
serializer = ConfiguracionFinanzasSerializer(configuracion, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class FinanzasBalanceView(APIView):
permission_classes = [IsAuthenticated]

def get(self, request):
usuario_info = request.user.userInfo

# Obtención de los balances por periodo
ingresos_totales = obtener_balance_por_periodo('INGRESO', 'total', usuario_info)
ingresos_cotizados_totales = obtener_balance_por_periodo('INGRESO_COTIZADO', 'total', usuario_info)
gastos_totales = obtener_balance_por_periodo('GASTO', 'total', usuario_info)

ingresos_mes = obtener_balance_por_periodo('INGRESO', 'mensual', usuario_info)
ingresos_cotizados_mes = obtener_balance_por_periodo('INGRESO_COTIZADO', 'mensual', usuario_info)
gastos_mes = obtener_balance_por_periodo('GASTO', 'mensual', usuario_info)

ingresos_trimestre = obtener_balance_por_periodo('INGRESO', 'trimestral', usuario_info)
ingresos_cotizados_trimestre = obtener_balance_por_periodo('INGRESO_COTIZADO', 'trimestral', usuario_info)
gastos_trimestre = obtener_balance_por_periodo('GASTO', 'trimestral', usuario_info)

ingresos_anio = obtener_balance_por_periodo('INGRESO', 'anual', usuario_info)
ingresos_cotizados_anio = obtener_balance_por_periodo('INGRESO_COTIZADO', 'anual', usuario_info)
gastos_anio = obtener_balance_por_periodo('GASTO', 'anual', usuario_info)

return Response({
'ingresos_totales': ingresos_totales,
'ingresos_cotizados_totales': ingresos_cotizados_totales,
'gastos_totales': gastos_totales,
'ingresos_mes': ingresos_mes,
'ingresos_cotizados_mes': ingresos_cotizados_mes,
'gastos_mes': gastos_mes,
'ingresos_trimestre': ingresos_trimestre,
'ingresos_cotizados_trimestre': ingresos_cotizados_trimestre,
'gastos_trimestre': gastos_trimestre,
'ingresos_anio': ingresos_anio,
'ingresos_cotizados_anio': ingresos_cotizados_anio,
'gastos_anio':  gastos_anio,
})
< /code>
my serializers.py < /p>
from rest_framework import serializers
from django.db import models
from finanzas.models import Transaccion, ConfiguracionFinanzas
from citas.models import Citas
from userinfo.models import UserInfo
from patients.models import Patient
from django.contrib.auth.models import User
from rest_framework.exceptions import ValidationError
from datetime import datetime

class UserSerializer(serializers.ModelSerializer):

class Meta:
model = User
fields = ['id', 'first_name', 'last_name', 'user']

class UserInfoSerializer(serializers.ModelSerializer):
user = UserSerializer()

class Meta:
model = UserInfo
fields = ['user', 'address',  'dni', 'postal_code', 'city', 'country', 'segundo_apellido']

def get_user(self, obj):
# Asegúrate de que el objeto user esté presente y se pase correctamente
return UserSerializer(obj.user).data if obj.user else None

class PatientSerializers(serializers.ModelSerializer):
class Meta:
model = Patient
fields = ['nombre', 'primer_apellido', 'segundo_apellido', 'dni', 'address', 'city', 'code_postal', 'country']

class CitaSerializers(serializers.ModelSerializer):
patient = PatientSerializers()
user = UserInfoSerializer()

class Meta:
model = Citas
fields = ['patient', 'fecha', 'descripcion', 'precio', 'cotizada', 'user']

def validate_precio(self, value):
if value < 0:
raise ValidationError("El precio de la cita no puede ser negativo.")
return value

def validate(self, data):
if data.get('fecha') > datetime.now():
raise ValidationError("La fecha de la cita no puede ser en el futuro.")
return data

class ConfiguracionFinanzasSerializer(serializers.ModelSerializer):
class Meta:
model = ConfiguracionFinanzas
fields = ['id', 'precio_cita_base', 'ultima_actualizacion']

def validate_precio_cita_base(self, value):
if value < 0:
raise ValidationError("El precio base de la cita no puede ser negativo.")
return value

class TransaccionSerializer(serializers.ModelSerializer):
cita = CitaSerializers()
user = UserInfoSerializer()

class Meta:
model = Transaccion
fields = ['id', 'tipo', 'monto', 'descripcion', 'fecha', 'cita', 'user', 'url']

def validate_monto(self, value):
if value 

Подробнее здесь: [url]https://stackoverflow.com/questions/79388272/attributeerror-with-user-in-django-application[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»