我创建了一个创建CompletedTest对象的序列化程序。当我创建create方法时,我需要传递2个新变量:one - " test"包含测试ID,另一个" user_list"包含用户列表' ids,例如:[1,2,3,4]。我设法通过"测试"包含测试ID,但我无法通过" user_list"。
models.py
class CompletedTest(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
test = models.ForeignKey(Test)
created = models.DateTimeField()
completed_with = models.ManyToManyField('self', blank=True)
serializers.py
class CompletedTestSerializer(serializers.Serializer):
test = serializers.CharField(source='test.id')
user_list = serializers.ListField(child=serializers.IntegerField())
def create(self, validated_data):
test = validated_data['test']
users = CustomUser.objects.filter(id__in=validated_data['user_list'])
for user in users:
try:
CompletedTest.objects.get(test_id=test, user_id=user)
except CompletedTest.DoesNotExist:
completed_test = CompletedTest.objects.all()
completed_test.create(user=user, test=test, created=timezone.now())
completed_test.get(user=user).completed_with = completed_test.exclude(user=user)
def update(self, instance, validated_data):
pass
views.py
class CompletedTestView(ListAPIView):
queryset = CompletedTest.objects.order_by('id')
serializer_class = CompletedTestSerializer
permission_classes = (IsAuthenticatedOrReadOnly, )
def post(self, request):
comp = CompletedTestSerializer(data=request.data)
comp.is_valid(raise_exception=True)
comp.save()
return Response({'success': True})
在我的测试中,这就是我传递的内容:
{
"test": 1,
"user_list": [1,2,3]
}
使用当前的user_list变量,我收到此错误:
Traceback:
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
41. response = get_response(request)
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/django/views/decorators/csrf.py" in wrapped_view
58. return view_func(*args, **kwargs)
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/django/views/generic/base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/rest_framework/views.py" in dispatch
489. response = self.handle_exception(exc)
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/rest_framework/views.py" in handle_exception
449. self.raise_uncaught_exception(exc)
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/rest_framework/views.py" in dispatch
486. response = handler(request, *args, **kwargs)
File "/home/alex/Documents/Proiecte/Django/escaper/application/location/views.py" in post
328. comp.save()
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/rest_framework/serializers.py" in save
215. self.instance = self.create(validated_data)
File "/home/alex/Documents/Proiecte/Django/escaper/application/location/serializers.py" in create
90. CompletedTest.objects.get(test_id=test, user_id=user)
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/django/db/models/manager.py" in manager_method
85. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/django/db/models/query.py" in get
371. clone = self.filter(*args, **kwargs)
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/django/db/models/query.py" in filter
784. return self._filter_or_exclude(False, *args, **kwargs)
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/django/db/models/query.py" in _filter_or_exclude
802. clone.query.add_q(Q(*args, **kwargs))
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/django/db/models/sql/query.py" in add_q
1250. clause, _ = self._add_q(q_object, self.used_aliases)
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/django/db/models/sql/query.py" in _add_q
1276. allow_joins=allow_joins, split_subq=split_subq,
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/django/db/models/sql/query.py" in build_filter
1206. condition = lookup_class(lhs, value)
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/django/db/models/lookups.py" in __init__
24. self.rhs = self.get_prep_lookup()
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/django/db/models/fields/related_lookups.py" in get_prep_lookup
112. self.rhs = target_field.get_prep_value(self.rhs)
File "/home/alex/Documents/Proiecte/Django/escaper/venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py" in get_prep_value
966. return int(value)
Exception Type: TypeError at /tests/completed/
Exception Value: int() argument must be a string, a bytes-like object or a number, not 'dict'
答案 0 :(得分:0)
用户是queryset,因此用户中的用户是User实例。
try:
CompletedTest.objects.get(test_id=test, user=user)
except CompletedTest.DoesNotExist:
....
或者您可以这样写:
for user in validated_data['user_list']:
try:
CompletedTest.objects.get(test_id=test, user_id=user)
except CompletedTest.DoesNotExist:
顺便说一下,ModelSerializer最简单。
class CompletedTestSerializer(ModelSerializer):
class Meta:
model = CompletedTest
fields = '__all__'
邮递员应该是:
不是:
创建的可以更改为created = models.DateTimeField(auto_now_add=True)
,然后默认情况下可以将Django设置为现在。
completed_room.get(user_id=user).completed_with = completed_room.exclude(user_id=user)
意味着添加CompletedRooms的completed_with设置为CompletedRooms,在创建后不属于此用途?如果是,signal是实现此目的的好方法:
完成/ signals.py
from datetime import datetime
from django.dispatch import receiver
from django.db.models.signals import post_save
from .models import CompletedTest
@receiver(post_save, sender=CompletedTest)
def set_completed_with(sender, instance=None, created=False, **kwargs):
if created:
not_belongs = CompletedTest.objects.exclude(user=instance.user)
instance.completed_with.add(*not_belongs)
instance.save()
完成/ app.py:
from django.apps import AppConfig
class CompletedConfig(AppConfig):
name = 'Completed'
verbose_name = 'Completed'
def ready(self):
import completed.signals
答案 1 :(得分:0)
你可以做这样的事情
class CompletedTestSerializer(serializers.Serializer):
test = serializers.CharField(source='test.id')
user_list = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
现在您可以在序列化程序函数中获取user_list