如何在Django Rest框架中为登录用户从数据库返回数据?
场景:如何在Django Rest框架中为登录用户从数据库返回数据?,django,python-3.x,django-rest-framework,Django,Python 3.x,Django Rest Framework,场景: from django.db import models from django.contrib.auth.models import User class UserData(models.Model): user = models.OneToOneField(User, on_delete = models.CASCADE) company = models.CharField(max_length=100, blank=True, null=True) ad
from django.db import models
from django.contrib.auth.models import User
class UserData(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
company = models.CharField(max_length=100, blank=True, null=True)
address = models.TextField()
class RegisterAPI(APIView):
permission_classes = [AllowAny]
def post(self, request, format=None):
serializer = UserDataSerializer(data=request.data)
if serializer.is_valid():
content = {
'status': 'Thanks for registering'}
return Response(content, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class LoginAPI(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
def list(self, request, *args, **kwargs):
user_id = request.user.id
queryset = User.objects.filter(user = request.user)
user_serializer = UserSerializer(queryset, many = True)
return Response(user_serializer.data)
from rest_framework import serializers
from users.models import UserData
from django.contrib.auth.models import User
class UserDataSerializer(serializers.ModelSerializer):
class Meta:
model = UserData
fields = ('company', 'address')
class UserSerializer(serializers.ModelSerializer):
info = UserDataSerializer()
class Meta:
model = User
fields = ('username', 'email', 'password', 'info')
def create(self, validated_data):
p_data = validated_data['info']
password = validated_data['password', None]
user = User.objects.create(**validated_data)
if password is not None:
user.set_password(password)
user.save()
UserData.objects.create(user = user, **p_data)
return validated_data
from rest_framework.routers import DefaultRouter
from users.views import LoginAPI, RegisterAPI
router = DefaultRouter()
router.register('login_api', LoginAPI, basename = 'login_api')
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
path('register_api/', RegisterAPI.as_view(), name = 'register_api'),
]
我目前有两个API。一个RegisterAPI和一个LoginAPI。RegisterAPI注册一个新用户,LoginAPI只允许他们访问其详细信息。我还使用了JWT身份验证
我想从数据库中检索使用DRF中的登录API登录的特定用户的数据。我的意图是与数据库交互,但问题是,我的序列化程序中有两个模型,它们是一对一的关系,我对如何解决这个问题感到困惑。要获得更清晰的图片,请查看下面的代码:
型号。py:
from django.db import models
from django.contrib.auth.models import User
class UserData(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
company = models.CharField(max_length=100, blank=True, null=True)
address = models.TextField()
class RegisterAPI(APIView):
permission_classes = [AllowAny]
def post(self, request, format=None):
serializer = UserDataSerializer(data=request.data)
if serializer.is_valid():
content = {
'status': 'Thanks for registering'}
return Response(content, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class LoginAPI(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
def list(self, request, *args, **kwargs):
user_id = request.user.id
queryset = User.objects.filter(user = request.user)
user_serializer = UserSerializer(queryset, many = True)
return Response(user_serializer.data)
from rest_framework import serializers
from users.models import UserData
from django.contrib.auth.models import User
class UserDataSerializer(serializers.ModelSerializer):
class Meta:
model = UserData
fields = ('company', 'address')
class UserSerializer(serializers.ModelSerializer):
info = UserDataSerializer()
class Meta:
model = User
fields = ('username', 'email', 'password', 'info')
def create(self, validated_data):
p_data = validated_data['info']
password = validated_data['password', None]
user = User.objects.create(**validated_data)
if password is not None:
user.set_password(password)
user.save()
UserData.objects.create(user = user, **p_data)
return validated_data
from rest_framework.routers import DefaultRouter
from users.views import LoginAPI, RegisterAPI
router = DefaultRouter()
router.register('login_api', LoginAPI, basename = 'login_api')
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
path('register_api/', RegisterAPI.as_view(), name = 'register_api'),
]
视图。py:
from django.db import models
from django.contrib.auth.models import User
class UserData(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
company = models.CharField(max_length=100, blank=True, null=True)
address = models.TextField()
class RegisterAPI(APIView):
permission_classes = [AllowAny]
def post(self, request, format=None):
serializer = UserDataSerializer(data=request.data)
if serializer.is_valid():
content = {
'status': 'Thanks for registering'}
return Response(content, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class LoginAPI(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
def list(self, request, *args, **kwargs):
user_id = request.user.id
queryset = User.objects.filter(user = request.user)
user_serializer = UserSerializer(queryset, many = True)
return Response(user_serializer.data)
from rest_framework import serializers
from users.models import UserData
from django.contrib.auth.models import User
class UserDataSerializer(serializers.ModelSerializer):
class Meta:
model = UserData
fields = ('company', 'address')
class UserSerializer(serializers.ModelSerializer):
info = UserDataSerializer()
class Meta:
model = User
fields = ('username', 'email', 'password', 'info')
def create(self, validated_data):
p_data = validated_data['info']
password = validated_data['password', None]
user = User.objects.create(**validated_data)
if password is not None:
user.set_password(password)
user.save()
UserData.objects.create(user = user, **p_data)
return validated_data
from rest_framework.routers import DefaultRouter
from users.views import LoginAPI, RegisterAPI
router = DefaultRouter()
router.register('login_api', LoginAPI, basename = 'login_api')
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
path('register_api/', RegisterAPI.as_view(), name = 'register_api'),
]
序列化程序。py:
from django.db import models
from django.contrib.auth.models import User
class UserData(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
company = models.CharField(max_length=100, blank=True, null=True)
address = models.TextField()
class RegisterAPI(APIView):
permission_classes = [AllowAny]
def post(self, request, format=None):
serializer = UserDataSerializer(data=request.data)
if serializer.is_valid():
content = {
'status': 'Thanks for registering'}
return Response(content, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class LoginAPI(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
def list(self, request, *args, **kwargs):
user_id = request.user.id
queryset = User.objects.filter(user = request.user)
user_serializer = UserSerializer(queryset, many = True)
return Response(user_serializer.data)
from rest_framework import serializers
from users.models import UserData
from django.contrib.auth.models import User
class UserDataSerializer(serializers.ModelSerializer):
class Meta:
model = UserData
fields = ('company', 'address')
class UserSerializer(serializers.ModelSerializer):
info = UserDataSerializer()
class Meta:
model = User
fields = ('username', 'email', 'password', 'info')
def create(self, validated_data):
p_data = validated_data['info']
password = validated_data['password', None]
user = User.objects.create(**validated_data)
if password is not None:
user.set_password(password)
user.save()
UserData.objects.create(user = user, **p_data)
return validated_data
from rest_framework.routers import DefaultRouter
from users.views import LoginAPI, RegisterAPI
router = DefaultRouter()
router.register('login_api', LoginAPI, basename = 'login_api')
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
path('register_api/', RegisterAPI.as_view(), name = 'register_api'),
]
url.py:
from django.db import models
from django.contrib.auth.models import User
class UserData(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
company = models.CharField(max_length=100, blank=True, null=True)
address = models.TextField()
class RegisterAPI(APIView):
permission_classes = [AllowAny]
def post(self, request, format=None):
serializer = UserDataSerializer(data=request.data)
if serializer.is_valid():
content = {
'status': 'Thanks for registering'}
return Response(content, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class LoginAPI(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
def list(self, request, *args, **kwargs):
user_id = request.user.id
queryset = User.objects.filter(user = request.user)
user_serializer = UserSerializer(queryset, many = True)
return Response(user_serializer.data)
from rest_framework import serializers
from users.models import UserData
from django.contrib.auth.models import User
class UserDataSerializer(serializers.ModelSerializer):
class Meta:
model = UserData
fields = ('company', 'address')
class UserSerializer(serializers.ModelSerializer):
info = UserDataSerializer()
class Meta:
model = User
fields = ('username', 'email', 'password', 'info')
def create(self, validated_data):
p_data = validated_data['info']
password = validated_data['password', None]
user = User.objects.create(**validated_data)
if password is not None:
user.set_password(password)
user.save()
UserData.objects.create(user = user, **p_data)
return validated_data
from rest_framework.routers import DefaultRouter
from users.views import LoginAPI, RegisterAPI
router = DefaultRouter()
router.register('login_api', LoginAPI, basename = 'login_api')
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
path('register_api/', RegisterAPI.as_view(), name = 'register_api'),
]
我想在LoginAPI中返回用户的用户名、电子邮件、公司和地址。这些都来自用户模型和配置文件模型。
例如:
{'username' = 'Tim',
'email' = 'tim@company.com',
'company' = 'Riko',
'address' = 'Kenya'}
但是,在访问登录API URL时,我无法从用户模型和配置文件模型检索记录
我得到这个错误:
AttributeError at /login_api/
Got AttributeError when attempting to get a value for field `info` on serializer `UserSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `User` instance.
Original exception text was: 'User' object has no attribute 'info'.**
有人能向我解释一下哪里出了问题吗?DRF serializers子类
Field
(serializers.Field
),因此您可以使用source
参数引用应该用于解析字段值的属性(UserDataSerializer
):
你得到的错误是不言自明的。您正在将一个
User
实例传递给UserSerializer
,但您有一个定义为info
的字段。由于用户
实例没有这样的属性,因此它会显示错误。因此,您需要某种方法来告诉序列化程序字段的值,使用source
引用现有属性是一种方法。您可以尝试将source传递给:info=UserDataSerializer(source='userdata')为什么要在源参数中包含“userdata”?我已经尝试过了,但在POSTMAN中看不到数据。相反,我得到的是:{'Detail':'User not found','code':User_not_found'}@danny_boy请完全按照我所做的做,并返回您所得到的结果。尽管您提出了以下建议,我仍然得到了相同的结果:(除了serializers.py之外,我的另一个代码,即views.py中的list方法有什么问题吗?@danny_boy你的名字到处都是。你在UserSeralizer.create
中,在UserdataSerializer.Meta.model
中将模型设置为userData
(不是UserData
)。感谢您的更正。我不知道为什么,但它仍然不起作用。此外,当我添加源参数时,我无法在Register API中创建用户。