|
3 | 3 | import pytest
|
4 | 4 | from _pytest.monkeypatch import MonkeyPatch
|
5 | 5 | from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
|
6 |
| -from django.test import override_settings |
| 6 | +from django.db import models |
| 7 | +from django.test import TestCase, override_settings |
7 | 8 | from django.urls import re_path
|
8 | 9 | from django.utils.datastructures import MultiValueDict
|
| 10 | +from django.utils.translation import gettext_lazy as _ |
9 | 11 |
|
10 | 12 | from rest_framework import relations, serializers
|
11 | 13 | from rest_framework.fields import empty
|
12 | 14 | from rest_framework.test import APISimpleTestCase
|
| 15 | +from tests.models import RESTFrameworkModel |
13 | 16 |
|
14 | 17 | from .utils import (
|
15 | 18 | BadType, MockObject, MockQueryset, fail_reverse, mock_reverse
|
@@ -518,3 +521,102 @@ def test_can_be_pickled(self):
|
518 | 521 | upkled = pickle.loads(pickle.dumps(self.default_hyperlink))
|
519 | 522 | assert upkled == self.default_hyperlink
|
520 | 523 | assert upkled.name == self.default_hyperlink.name
|
| 524 | + |
| 525 | + |
| 526 | +class Address(RESTFrameworkModel): |
| 527 | + postal_code = models.CharField( |
| 528 | + max_length=20, unique=True, verbose_name=_("Postal Code") |
| 529 | + ) |
| 530 | + province = models.CharField(max_length=100, verbose_name=_("Province")) |
| 531 | + city = models.CharField(max_length=100, verbose_name=_("City")) |
| 532 | + street = models.CharField( |
| 533 | + max_length=255, blank=True, null=True, verbose_name=_("Street") |
| 534 | + ) |
| 535 | + additional_info = models.TextField( |
| 536 | + verbose_name=_("Additional Info"), blank=True, null=True |
| 537 | + ) |
| 538 | + |
| 539 | + |
| 540 | +class AddressSerializer(serializers.ModelSerializer): |
| 541 | + class Meta: |
| 542 | + model = Address |
| 543 | + fields = "__all__" |
| 544 | + |
| 545 | + |
| 546 | +class SerializedRelatedFieldTests(TestCase): |
| 547 | + |
| 548 | + class OrderSerializerPostalCode(serializers.Serializer): |
| 549 | + address = relations.SerializedRelatedField( |
| 550 | + serializer_class=AddressSerializer, |
| 551 | + queryset=Address.objects.all(), |
| 552 | + lookup_field='postal_code', |
| 553 | + ) |
| 554 | + |
| 555 | + class OrderSerializerCity(serializers.Serializer): |
| 556 | + address = relations.SerializedRelatedField( |
| 557 | + serializer_class=AddressSerializer, |
| 558 | + queryset=Address.objects.all(), |
| 559 | + lookup_field='city', |
| 560 | + ) |
| 561 | + |
| 562 | + class OrderSerializerPK(serializers.Serializer): |
| 563 | + address = relations.SerializedRelatedField( |
| 564 | + serializer_class=AddressSerializer, |
| 565 | + queryset=Address.objects.all(), |
| 566 | + ) |
| 567 | + |
| 568 | + def setUp(self): |
| 569 | + self.address = Address.objects.create( |
| 570 | + postal_code="12345", |
| 571 | + province="Tehran", |
| 572 | + city="Tehran", |
| 573 | + street="Valiasr", |
| 574 | + additional_info="Test info" |
| 575 | + ) |
| 576 | + Address.objects.create( |
| 577 | + postal_code="123456", |
| 578 | + province="Tehran", |
| 579 | + city="Tehran", |
| 580 | + street="Valiasr", |
| 581 | + additional_info="Test info" |
| 582 | + ) |
| 583 | + |
| 584 | + def test_write_slug(self): |
| 585 | + data = {"address": self.address.postal_code} |
| 586 | + serializer = self.OrderSerializerPostalCode(data=data) |
| 587 | + assert serializer.is_valid(), serializer.errors |
| 588 | + assert serializer.validated_data["address"] == self.address |
| 589 | + |
| 590 | + def test_read_nested(self): |
| 591 | + data = {"address": self.address.postal_code} |
| 592 | + serializer = self.OrderSerializerPostalCode(data=data) |
| 593 | + assert serializer.is_valid(), serializer.errors |
| 594 | + expected = AddressSerializer(self.address).data |
| 595 | + assert serializer.data["address"] == expected |
| 596 | + |
| 597 | + def test_write_default(self): |
| 598 | + data = {"address": self.address.pk} |
| 599 | + serializer = self.OrderSerializerPK(data=data) |
| 600 | + assert serializer.is_valid(), serializer.errors |
| 601 | + expected = AddressSerializer(self.address).data |
| 602 | + assert serializer.data["address"] == expected |
| 603 | + |
| 604 | + def test_read_default(self): |
| 605 | + data = {"address": self.address.pk} |
| 606 | + serializer = self.OrderSerializerPK(data=data) |
| 607 | + assert serializer.is_valid(), serializer.errors |
| 608 | + expected = AddressSerializer(self.address).data |
| 609 | + assert serializer.data["address"] == expected |
| 610 | + |
| 611 | + def test_duplicated(self): |
| 612 | + data = {"address": "Tehran"} |
| 613 | + serializer = self.OrderSerializerCity(data=data) |
| 614 | + with pytest.raises(Address.MultipleObjectsReturned) as exc_info: |
| 615 | + serializer.is_valid(raise_exception=True) |
| 616 | + assert "returned more than one Address -- it returned 2!" in str(exc_info.value) |
| 617 | + |
| 618 | + def test_not_fount(self): |
| 619 | + data = {"address": "Isfahan"} |
| 620 | + serializer = self.OrderSerializerCity(data=data) |
| 621 | + serializer.is_valid() |
| 622 | + assert "Object with city=Isfahan does not exist." in serializer.errors["address"] |
0 commit comments