在Django / Python中调用Profile.object.create时发生TypeError

时间:2019-04-25 02:11:02

标签: python django django-rest-framework

尝试创建新的配置文件时出现以下错误。

Got a `TypeError` when calling `Profile.objects.create()`. This may be because you have a writable field on the serializer class that is not a valid argument to `Profile.objects.create()`. You may need to make the field read-only, or override the ProfileSerializer.create() method to handle this correctly.
Original exception was:

我不确定为什么会出现此错误。

我有一个模型和序列化器以及视图和URL。我什至不确定过程中的错误来自哪里。

models.py

class Profile(models.Model):
    user = models.ForeignKey(
        User, on_delete=models.CASCADE
    )
    synapse = models.CharField(max_length=25, null=True)
    bio = models.TextField(null=True)
    profile_pic = models.ImageField(upload_to='./profile_pics/',
                                    height_field=500,
                                    width_field=500,
                                    max_length=150)
    facebook = models.URLField(max_length=150)
    twitter = models.URLField(max_length=150)
    updated = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.user.username + self.synapse

profileViews.py

from users.models import Profile

from rest_framework.generics import ListAPIView, RetrieveAPIView, CreateAPIView
from rest_framework.generics import DestroyAPIView, UpdateAPIView

from users.api.serializers import ProfileSerializer


class ProfileListView(ListAPIView):
    queryset = Profile.objects.all()
    serializer_class = ProfileSerializer


class ProfileRetrieveView(RetrieveAPIView):
    queryset = Profile.objects.all()
    serializer_class = ProfileSerializer


class ProfileCreateView(CreateAPIView):
    queryset = Profile.objects.all()
    serializer_class = ProfileSerializer


class ProfileDestroyView(DestroyAPIView):
    queryset = Profile.objects.all()
    serializer_class = ProfileSerializer


class ProfileUpdateView(UpdateAPIView):
    queryset = Profile.objects.all()
    serializer_class = ProfileSerializer

urls.py

from django.urls import path

from users.api.views.profileViews import ProfileListView, ProfileRetrieveView, ProfileCreateView
from users.api.views.profileViews import ProfileDestroyView, ProfileUpdateView

urlpatterns = [
    path('', ProfileListView.as_view()),
    path('create/', ProfileCreateView.as_view()),
    path('update/<pk>/', ProfileUpdateView.as_view()),
    path('delete/<pk>/', ProfileDestroyView.as_view()),
    path('<pk>/', ProfileRetrieveView.as_view())
]

配置文件的序列化器

class ProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = (
            'id',
            'user',
            'synapse',
            'bio',
            'profile_pic',
            'facebook',
            'twitter'
        )

这是否意味着我需要指定图像类型。我希望个人资料图片位于主用户文件夹中。

enter image description here

2 个答案:

答案 0 :(得分:0)

按以下所示更改模型中的 profile_pic 字段。 ( 删除height_fieldwidth_field

profile_pic = models.ImageField(upload_to='./profile_pics/', max_length=150)

因为它们不是自动调整图像大小的内容。

请参见此'getattr(): attribute name must be string' error in admin panel for a model with an ImageField帖子


除此之外,由于您正在处理 CRUD 应用程序,因此我建议您在代码中将ModelViewsetDRF Routers一起使用。 / p>

答案 1 :(得分:-1)

将您的ProfileSerializer更新为

class ProfileSerializer(serializers.ModelSerializer):

    user = UserSerializer(many=False, read_only=True)
    class Meta:
        model = Profile
        fields = (
            'id',
            'user',
            'synapse',
            'bio',
            'profile_pic',
            'facebook',
            'twitter'
        )

关于您的观点,我建议用户ModelViewSet代替。看到您使用默认方法,所以只需要:

class ProfileViewSet(viewsets.ModelViewSet):
    queryset = Profile.objects.all()
    serializer_class = ProfileSerializer

urls.py

from rest_framework import routers


router = routers.SimpleRouter()

router.register('profiles', ProfileViewSet, base_name='profile')
urlpatterns = [
    ...,
    url('/api', include(router.urls)),
]

这适用于RESTful API,例如:

  • 获取列表:domain.com/api/profiles/(GET方法)

  • 创建新的配置文件:domain.com/api/profiles/(POST方法)