HyperlinkedRelatedFIeld и отношения OneToOne - объект не имеет атрибута
В моем приложении есть офисы и пользователи HR (пользователи с полем OneToOneField в HRProfile), и я хочу иметь возможность назначать HR в офисы. Проблема, с которой я столкнулся, заключается в том, что я просто не могу получить доступ к полю 'email' пользователя, когда пытаюсь найти его через HyperlinkedRelatedField на OfficeSerializer.
.
Соответствующие модели:
class User(AbstractBaseUser, PermissionsMixin):
...
email = models.EmailField(unique=True)
...
from polymorphic.models import PolymorphicModel
class Profile(PolymorphicModel):
...
related_user = models.OneToOneField(settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL,
related_name="profile",
)
...
class HRProfile(Profile):
some_hr_specific_field = models.CharField()
def __str__(self) -> str:
return self.related_user.email
class Office(models.Model):
...
assigned_hrs = models.ManyToManyField(
"users.HRProfile", related_name="offices", blank=True
)
...
Вид:
class UserViewSet(
GenericViewSet,
):
serializer_class = UserSerializer
queryset = User.objects.all()
lookup_field = "email"
lookup_url_kwarg = "email"
lookup_value_regex = "[\\w@.]+"
...
# the OfficeViewSet just has the two required fields (queryset and serializer)
А вот с OfficeSerializer у меня проблемы:
class OfficeSerializer(serializers.HyperlinkedModelSerializer):
...
assigned_hrs = serializers.HyperlinkedRelatedField(
queryset=HRProfile.objects.all(),
view_name="api:user-detail",
lookup_field="related_user.email",
many=True,
)
...
Вышеуказанное вызывает 'HRProfile' object has no attribute 'related_user.email'
, который я не знаю, что делать, поскольку HRProfile.__str__
не имеет проблем с правильным разрешением self.related_user.email
пути для данного пользователя.
Я попробовал с source='assigned_hrs.related_user', lookup_field='email'
, но безрезультатно. Также я попробовал заменить HyperlinkedRelatedField на SlugRelatedField просто для проверки, и это та же проблема с slug_field="related_user.email"
. Я также попробовал использовать двойное подчеркивание вместо точки. Однако в результате получается lookup_field='some_hr_specific_field'
, что, конечно, не то, чего я хочу, но проблема решается.
У меня уже нет идей, и любые подсказки будут очень признательны!
Решено!
Определить get_hrs в модели Office:
class Office(models.Model):
def get_hrs(self):
hrs = self.assigned_hrs.all()
return [hr.related_user for hr in hrs]
<
class OfficeSerializer(serializers.HyperlinkedModelSerializer):
assigned_hrs = serializers.HyperlinkedRelatedField(
many=True,
queryset=User.objects.filter(groups__name="human_resource"),
source="get_hrs",
lookup_field="email",
view_name="api:user-detail",
)
# slugrelated works too :)
# assigned_hrs = serializers.SlugRelatedField(
# many=True,
# queryset=User.objects.filter(groups__name="human_resource"),
# source="get_hrs",
# slug_field="email",
# )