向serializ传递额外变量的DRF

2024-06-02 17:49:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我做了一个序列化程序来创建一个CompletedTest对象。当我创建create方法时,我需要传递两个新变量:一个是包含测试id的“test”,另一个是包含用户id的列表的“user_list”,例如:[1,2,3,4]。我设法通过了包含测试id的“test”,但我无法通过“user_list”。在

模型.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)

序列化程序.py

^{pr2}$

视图.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'

Tags: djangoinpyselfhomevenvmodelslib
2条回答

你可以这样做

class CompletedTestSerializer(serializers.Serializer):
   test = serializers.CharField(source='test.id')
   user_list = serializers.PrimaryKeyRelatedField(read_only=True, many=True)

现在可以在序列化程序函数中获取用户列表

Users是queryset,所以Users中的user是一个用户实例。在

try:
    CompletedTest.objects.get(test_id=test, user=user)
except CompletedTest.DoesNotExist:
    ....

或者你可以这样写:

^{pr2}$

顺便说一下,ModelSerializer是最简单的。在

class CompletedTestSerializer(ModelSerializer):

    class Meta:
        model = CompletedTest
        fields = '__all__'

邮递员应: enter image description here 不是: enter image description here

created可以更改为created = models.DateTimeField(auto_now_add=True),然后Django可以将其默认设置为now。在

completed_room.get(user_id=user).completed_with = completed_room.exclude(user_id=user)

意思是添加CompletedRooms的CompletedRooms的CompletedRooms设置为create后不属于此用途的CompletedRooms?如果是,信号是实现这一点的好方法:

已完成/信号.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()

已完成/应用程序副本公司名称:

from django.apps import AppConfig


class CompletedConfig(AppConfig):
    name = 'Completed'
    verbose_name = 'Completed'

    def ready(self):
        import completed.signals

相关问题 更多 >