我试图了解Django DRF,并尝试根据我的知识做一些复杂的事情。在我的应用程序中,我有邀请键,但是我只想允许用户在3天后(如果这是他们的第一个键)创建邀请键。如何创建序列化程序并以更好的方式查看它?
我正在使用Django 2.1.5和DRF 3.9.1
我已经尝试并在网络上阅读了其他问题,但是无法很好地实现自己想要的目标。我所想到的只是薄的视图,厚的串行器。
导致我的视图部分无法正常工作Object of type 'AttributeError' is not JSON serializable
这个错误是我的观点,我知道很多。
我的模特:
class Invite_Key(models.Model):
STATUS_CHOICES = (
('valid', 'valid'),
('not_valid', 'not_valid'),
('banned', 'banned'),
)
# Foreign keys
user_submitter = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
null=True,
blank=True,
related_name='user_submitter'
)
user_receiver = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
null=True,
blank=True,
related_name='user_receiver'
)
uuid = models.UUIDField(default=generate_ulid_as_uuid, editable=False, unique=True, null=False)
open_uuid = models.UUIDField(default=uuid1, editable=False, unique=True, null=False)
reason = models.TextField(validators=[bad_words, bad_words_inline, test_test])
# Now are choices
status = models.CharField(max_length=14, choices=STATUS_CHOICES, default="valid")
# Now below are boolean
is_taken = models.BooleanField(default=False)
is_locked = models.BooleanField(default=False)
claim_date = models.DateField(editable=True, null=True, blank=True)
expire_date = models.DateField(editable=True, null=True, blank=True)
# Now these are the time stamps
created_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True, editable=False)
def __str__(self):
return str(self.uuid)
# An instance of our object temp used for later
def __init__(self, *args, **kwargs):
super(Invite_Key, self).__init__(*args, **kwargs)
self.temp = ''
# We can set attributes onSave of our data to the table
def save(self, *args, **kwargs):
if not self.id:
# for expire date
self.expire_date = datetime.now() + timedelta(days=7)
super(Invite_Key, self).save(*args, **kwargs)
我的序列化器:
class InviteKeyCreateAllSerializer(serializers.ModelSerializer):
current_user = serializers.SerializerMethodField('_user')
is_take = serializers.SerializerMethodField()
class Meta:
model = Invite_Key
exclude = [
'user_submitter',
'user_receiver',
'uuid',
'status',
'is_taken',
'is_locked',
'claim_date',
'expire_date',
]
# Use this method for the custom field
def _user(self, obj):
request = getattr(self.context, 'request', None)
if request:
return request.user
def get_is_taken(self, obj):
return False
def get_status(self, obj):
return 'valid'
# end of custom fields
def create(self, validated_data):
key = Invite_Key(
user_submitter=validated_data['request.user'],
)
key.set_user_submitter(validated_data['user_submitter'])
key.save()
return key
我的观点
class InviteKeyAllCreateView(generics.CreateAPIView):
"""
POST invitekey/
"""
serializer_class = InviteKeyCreateAllSerializer
permission_classes = (IsAuthenticated,)
def post(self, request, *args, **kwargs):
user = self.request.user
try:
# get user count of keys
cur_key_count = Invite_Key.objects.filter(user_submitter_id=user.id).order_by('-created_at').count()
if cur_key_count > 0:
# now we get the latest one
check_key = Invite_Key.object.filter(user_submitter_id=user.id)[0]
now = datetime.now()
if now-timedelta(days=3) <= datetime.datetime.strptime(check_key['created_at'], "%Y-%m-%dT%H:%M:%S.%fZ"):
serialized_data = InviteKeyCreateAllSerializer(data=request.data)
serialized_data.is_valid(raise_exception=True)
serialized_data.save()
else:
return Response(
data={
"message": "Sorry, you have recently created an Invite Key, try again some other time."
},
status=status.HTTP_400_BAD_REQUEST
)
except Exception as e:
return Response(
data={
"message": "The Invite Key could not be created.",
"error": e
},
status=status.HTTP_400_BAD_REQUEST
)
我希望通过创建一个http发布请求来创建一个邀请密钥,该视图将检查用户是否已创建密钥,然后获取最新密钥,然后在创建新密钥之前检查密钥是否存在3天,然后序列化程序将填充发布请求中缺少的数据。
实际结果是我得到AttributeError。另外,是否可以将我的大多数视图逻辑移至串行器?有人可以给我提示吗?我在“序列化器和视图的DRF文档”中寻找类似的内容,但找不到太多。
如果我缺少一些信息,请告诉我,谢谢...
编辑:添加了模型类 编辑: 我更改为str(e),现在的错误是:
type object 'Invite_Key' has no attribute 'object'
编辑:添加了错误跟踪功能
Django Version: 2.1.5
Python Version: 3.6.8
Installed Applications:
['django.contrib.admin.apps.SimpleAdminConfig',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
'djmoney',
'api',
'main',
'rssparser',
'invite_system',
'user_system']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
34. response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
126. response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
124. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view
54. return view_func(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/django/views/generic/base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
495. response = self.handle_exception(exc)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py" in handle_exception
455. self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
492. response = handler(request, *args, **kwargs)
File "/opt/service/api/src/invite_system/views.py" in post
229. check_key = Invite_Key.object.filter(user_submitter_id=user.id).order_by('-created_at')[0]
Exception Type: AttributeError at /api/v1/invitekey
Exception Value: type object 'Invite_Key' has no attribute 'object'
编辑: 我正在调试中,并停留在下面的if语句的结构上。
错误:
'Invite_Key' object is not subscriptable
错误点:
now = datetime.now()
if now-timedelta(days=3) <= datetime.strptime(check_key['created_at'], "%Y-%m-%dT%H:%M:%S.%fZ"):
serialized_data = InviteKeyCreateAllSerializer(data=request.data)
if语句无法评估要格式化的check_key ['created_at']。什么是正确的方法?我正在使用Postgres作为时间戳。
答案 0 :(得分:1)
.......
except Exception as e:
return Response(
data={
"message": "The Invite Key could not be created.",
"error": e },
status=status.HTTP_400_BAD_REQUEST)
在上面的代码段中,变量 e
是任何有效Pycthon Exception类的 对象 ,显然不是可序列化。
以字符串格式表示对象
.......
except Exception as e:
return Response(
data={
"message": "The Invite Key could not be created.",
"error": str(e)
},
status=status.HTTP_400_BAD_REQUEST)
应为 objects
,而不是object
(缺少字符 s
)< / p>
check_key = Invite_Key.objects.filter(user_submitter_id=user.id)[0]