Django RestFramework-测试视图失败400

发布于 2025-01-30 18:05:57 字数 4485 浏览 2 评论 0原文

现在,我正在尝试为我的Views.py中的A listCreateapiview 创建一个简单的测试文件

REST_FRAMEWORK = {
    'TEST_REQUEST_DEFAULT_FORMAT': 'json'
}

views.py:

class AuthorListCreateView(ListCreateAPIView):
    queryset = Author.objects.all()
    serializer_class = AuthorSerializer

serializer.py:

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = '__all__'

urls.py:

urlpatterns = [
    path('author/', AuthorListCreateView.as_view(), name='author-list'),
]

型号

from django.contrib.auth import get_user_model

USER = get_user_model()


class BaseModel(models.Model):
    id = models.BigAutoField(primary_key=True, editable=False, unique=True)
    created_by = models.ForeignKey(USER, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True
        get_latest_by = 'created_at'


class Author(BaseModel):

    class Gender(models.TextChoices):
        NO = 'NO', 'No gender chosen'
        DIVERSE = 'DI', 'Diverse'
        FEMALE = 'FE', 'Female'
        MALE = 'MA', 'Male'

    first_name = models.CharField(max_length=50, null=False, blank=False)
    last_name = models.CharField(max_length=50, null=False, blank=False)
    born = models.DateField(null=False, blank=False)
    died = models.DateField(null=True, blank=True)
    passed = models.BooleanField(default=False)
    gender = models.CharField(max_length=2, choices=Gender.choices, default=Gender.NO)
    slug = models.SlugField(null=False, blank=False, unique=True)

    class Meta:
        ordering = ['last_name', 'first_name']
        constraints = [
            models.UniqueConstraint(fields=['last_name', 'first_name'], name='unique_name_constraint'),
        ]
        indexes = [
            models.Index(fields=['last_name', 'first_name'], name='index_unique_name'),
        ]
        verbose_name = 'Author'
        verbose_name_plural = 'Authors'

    def __str__(self) -> str:
        return f'{self.first_name} {self.last_name}'

    def save(self, *args, **kwargs):
        self.passed = True if self.died is not None else False
        self.slug = slugify(f'{self.last_name}-{self.first_name}') if not self.slug else self.slug
        super(Author, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('author-detail', kwargs={'slug': self.slug})

    def clean(self):
        if self.died is not None and self.born > self.died:
            raise ValidationError("Date of born can't be further in time than date of death!")

    @property
    def age(self):
        if self.passed:
            delta = self.died - self.born
            return delta.days // 365
        else:
            delta = date.today() - self.born
            return delta.days // 365

,如您所见是基本的,但是每当我试图测试我的视图时,我都会收到 http_400_bad_request !附带说明,使用实际API创建对象完美工作。

test_views.py:

import datetime
from django.contrib.auth import get_user_model
from django.urls import reverse
from django.utils import timezone
from rest_framework import status
from rest_framework.test import APITestCase
from ..models import Author


USER = get_user_model()


class AuthorTest(APITestCase):
    def test_create_obj(self):
        url = reverse('author-list')
        user = USER.objects.create_user('[email protected]', 'johndoepassword')

        data = {
            'id': 1,
            'first_name': 'Jane',
            'last_name': 'Doe',
            'born': datetime.date(1940, 1, 1),
            'died': datetime.date(2010, 12, 31),
            'passed': True,
            'gender': 'FE',
            'slug': 'doe-jane',
            'created_by': user,
            'created_at': timezone.now(),
            'updated_at': timezone.now(),
        }
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(Author.objects.count(), 1)
        self.assertEqual(Author.objects.get().first_name, 'Jane')

有人可以看到我缺少什么或在这里做错了什么?

right now I'm trying to create a simple test-file for a ListCreateAPIView inside my views.py:

Inside my settings.py I set json as default for testing purposes:

REST_FRAMEWORK = {
    'TEST_REQUEST_DEFAULT_FORMAT': 'json'
}

views.py:

class AuthorListCreateView(ListCreateAPIView):
    queryset = Author.objects.all()
    serializer_class = AuthorSerializer

serializers.py:

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = '__all__'

urls.py:

urlpatterns = [
    path('author/', AuthorListCreateView.as_view(), name='author-list'),
]

models.py

from django.contrib.auth import get_user_model

USER = get_user_model()


class BaseModel(models.Model):
    id = models.BigAutoField(primary_key=True, editable=False, unique=True)
    created_by = models.ForeignKey(USER, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True
        get_latest_by = 'created_at'


class Author(BaseModel):

    class Gender(models.TextChoices):
        NO = 'NO', 'No gender chosen'
        DIVERSE = 'DI', 'Diverse'
        FEMALE = 'FE', 'Female'
        MALE = 'MA', 'Male'

    first_name = models.CharField(max_length=50, null=False, blank=False)
    last_name = models.CharField(max_length=50, null=False, blank=False)
    born = models.DateField(null=False, blank=False)
    died = models.DateField(null=True, blank=True)
    passed = models.BooleanField(default=False)
    gender = models.CharField(max_length=2, choices=Gender.choices, default=Gender.NO)
    slug = models.SlugField(null=False, blank=False, unique=True)

    class Meta:
        ordering = ['last_name', 'first_name']
        constraints = [
            models.UniqueConstraint(fields=['last_name', 'first_name'], name='unique_name_constraint'),
        ]
        indexes = [
            models.Index(fields=['last_name', 'first_name'], name='index_unique_name'),
        ]
        verbose_name = 'Author'
        verbose_name_plural = 'Authors'

    def __str__(self) -> str:
        return f'{self.first_name} {self.last_name}'

    def save(self, *args, **kwargs):
        self.passed = True if self.died is not None else False
        self.slug = slugify(f'{self.last_name}-{self.first_name}') if not self.slug else self.slug
        super(Author, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('author-detail', kwargs={'slug': self.slug})

    def clean(self):
        if self.died is not None and self.born > self.died:
            raise ValidationError("Date of born can't be further in time than date of death!")

    @property
    def age(self):
        if self.passed:
            delta = self.died - self.born
            return delta.days // 365
        else:
            delta = date.today() - self.born
            return delta.days // 365

As you can see, the structure is pretty basic, but whenever I'm trying to test my view I'm receiving a HTTP_400_BAD_REQUEST! As a side note, creating an object with the actual api works perfectly.

test_views.py:

import datetime
from django.contrib.auth import get_user_model
from django.urls import reverse
from django.utils import timezone
from rest_framework import status
from rest_framework.test import APITestCase
from ..models import Author


USER = get_user_model()


class AuthorTest(APITestCase):
    def test_create_obj(self):
        url = reverse('author-list')
        user = USER.objects.create_user('[email protected]', 'johndoepassword')

        data = {
            'id': 1,
            'first_name': 'Jane',
            'last_name': 'Doe',
            'born': datetime.date(1940, 1, 1),
            'died': datetime.date(2010, 12, 31),
            'passed': True,
            'gender': 'FE',
            'slug': 'doe-jane',
            'created_by': user,
            'created_at': timezone.now(),
            'updated_at': timezone.now(),
        }
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(Author.objects.count(), 1)
        self.assertEqual(Author.objects.get().first_name, 'Jane')

Can someone see what I am missing or doing wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文