我使用Django 2.0
和Django REST Framework
撰写REST API
。
我的 settings.py 包含DRF的设置
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated'
]
}
并且必须使用任何DEFAULT_AUTHENTICATION_CLASSES
方法对每个请求进行签名。
在 contacts / serializers.py
中class ContactSerializer(serializers.HyperlinkedModelSerializer):
phone_numbers = ContactPhoneNumberSerializer(source='contactphonenumber_set', many=True)
class Meta:
model = Contact
fields = ('url', 'first_name', 'last_name', 'full_name', 'date_of_birth', 'phone_numbers')
def create(self, validated_data):
phone_numbers = validated_data.pop('contactphonenumber_set')
emails = validated_data.pop('contactemail_set')
instance = Contact.objects.create(**validated_data)
for phone_data in phone_numbers:
ContactPhoneNumber.objects.create(contact=instance, **phone_data)
return instance
print(validated_data)
提供以下数据
{'first_name': 'Anshuman', 'last_name': 'Upadhyay', 'date_of_birth': datetime.date(2018, 5, 15), 'contactphonenumber_set': [], 'user_id': <SimpleLazyObject: <User: anuj>>}
user_id
为SimpleLazyObject
,因此在保存
TypeError: int() argument must be a string, a bytes-like object or a number, not 'SimpleLazyObject'
错误在instance = Contact.objects.create(**validated_data)
如何将经过身份验证的用户传递到user
字段?
编辑2: contacts / models.py
class Contact(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100, blank=True, null=True)
date_of_birth = models.DateField(blank=True, null=True)
联系人/ views.py
class ContactViewSet(viewsets.ModelViewSet):
serializer_class = ContactSerializer
permission_classes = (IsAuthenticated, AdminAuthenticationPermission,)
def get_queryset(self):
return Contact.objects.filter(user=self.request.user)
def perform_create(self, serializer):
serializer.save(user_id=self.request.user)
答案 0 :(得分:1)
假设您的Contact
模型与AuthUserModel
包含FK关系。因此,您的实例创建语句必须是这样的,
user = get some user instance from `validated` data
instance = Contact.objects.create(user=user,**validated_data)
这是您的问题的一般解决方案,如果您添加Contact
模型,我们可以为您提供更多帮助
的 UPDATE-1 强>
如下所示更改create()
,
def create(self, validated_data):
phone_numbers = validated_data.pop('contactphonenumber_set')
emails = validated_data.pop('contactemail_set')
user = validated_data.pop('user') # change 1
instance = Contact.objects.create(user=user, **validated_data) # # change 2
for phone_data in phone_numbers:
ContactPhoneNumber.objects.create(contact=instance, **phone_data)
return instance
的更新-2 强>
您可以在序列化程序中使用user = serializers.CurrentUserDefault()
,如下所示,
class ContactSerializer(serializers.HyperlinkedModelSerializer):
phone_numbers = ContactPhoneNumberSerializer(source='contactphonenumber_set', many=True)
user = serializers.CurrentUserDefault()
class Meta:
model = Contact
fields = ('url', 'first_name', 'last_name', 'full_name', 'date_of_birth', 'phone_numbers')
def create(self, validated_data):
phone_numbers = validated_data.pop('contactphonenumber_set')
emails = validated_data.pop('contactemail_set')
user = validated_data.pop('user_id')
instance = Contact.objects.create(user=user, **validated_data)
for phone_data in phone_numbers:
ContactPhoneNumber.objects.create(contact=instance, **phone_data)
return instance
CurrentUserDefault()
与self.context.get('request').user
答案 1 :(得分:1)
您可以self.context
使用GenericAPIView
如果您正在使用user_id
上下文自动传递
首先,您不需要将ContactSerializer
传递给序列化程序,然后您需要将class ContactSerializer(serializers.HyperlinkedModelSerializer):
phone_numbers = ContactPhoneNumberSerializer(source='contactphonenumber_set', many=True)
class Meta:
model = Contact
fields = ('url', 'first_name', 'last_name', 'full_name', 'date_of_birth', 'phone_numbers')
def create(self, validated_data):
phone_numbers = validated_data.pop('contactphonenumber_set')
emails = validated_data.pop('contactemail_set')
instance = Contact.objects.create(user=self.context['request'].user, **validated_data)
for phone_data in phone_numbers:
ContactPhoneNumber.objects.create(contact=instance, **phone_data)
return instance
更新为这样。
perform_create
您不应该覆盖class ContactViewSet(viewsets.ModelViewSet):
serializer_class = ContactSerializer
permission_classes = (IsAuthenticated, AdminAuthenticationPermission,)
def get_queryset(self):
return Contact.objects.filter(user=self.request.user)
df = pd.read_csv(url,skiprows=7)