Я начинающий пользователь python/django, пытаюсь протестировать вложенный сериализатор и получаю 'TypeError: Direct assignment to the reverse side of a relatedset'
Я пытаюсь написать тест, чтобы показать, что я могу сериализовать клиента и передать подписки, на которые клиент подписался, в настоящее время только на одну подписку, но я верю, что то, что у меня есть, будет работать для нескольких подписок. Это мой первый раз, когда я делаю что-то на python, и я не знаю внутреннюю работу и не знаю, что я здесь напутал
Вот мой файл test_serializer.py
class CustomerSerializerTestCase(unittest.TestCase):
def setUp(self):
self.subscription_attributes = {
'title': 'Tea Partay',
'price': 50.99,
'status': 'active',
'frequency': 'monthly'
}
self.customer_attributes = {
'first_name': 'Hai',
'last_name': 'Sall',
'email': 'sailt&peppa@saimall.com',
'address': 'this place Seattle, WA',
'subscriptions': 'self.subscription.id'
}
self.subscription = Subscription.objects.create(**self.subscription_attributes)
self.serialzied_subscription = SubscriptionSerializer(instance=self.subscription)
self.customer = Customer.objects.create(**self.customer_attributes)
self.serialized_customer = CustomerSerializer(instance=self.customer)
def test_customer_serializer_has_correct_keys(self):
customer_att = {
'first_name': 'pachary',
'last_name': 'zrince',
'email': 'Ilovelittlekatanas@hotkatana.com',
'address': 'katana ln, maldorf, Waryland'
}
customer = Customer.objects.create(**customer_att)
serialized_customer = CustomerSerializer(instance = customer)
data = serialized_customer.data
self.assertEqual(set(data.keys()), set(['first_name', 'last_name', 'email', 'address', 'subscriptions']))
def test_customer_field_contents(self):
customer_data = self.serialized_customer.data
self.assertEqual(customer_data['first_name'], self.customer_attributes['first_name'])
self.assertEqual(customer_data['last_name'], self.customer_attributes['last_name'])
self.assertEqual(customer_data['email'], self.customer_attributes['email'])
self.assertEqual(customer_data['address'], self.customer_attributes['address'])
self.assertEqual(customer_data['subscriptions'], self.subscription_attributes['title'])
self.assertEqual(customer_data['subscriptions'], self.subscription_attributes['price'])
self.assertEqual(customer_data['subscriptions'], self.subscription_attributes['status'])
self.assertEqual(customer_data['subscriptions'], self.subscription_attributes['frequency'])
Вот мой models.py
class Tea(models.Model):#has_many :subscriptions
title = models.CharField(max_length = 100)
description = models.CharField(max_length = 1000)
temperature = models.IntegerField()
brew_time = models.IntegerField()
class Customer(models.Model):#has_many :subscriptions
first_name = models.CharField(max_length = 100)
last_name = models.CharField(max_length = 100)
email = models.EmailField(max_length = 300)
address = models.CharField(max_length = 500)
class Subscription(models.Model):#belongs_to :customers, :tea
status_choice = {
('active', 'active'),
('cancelled', 'cancelled')
}
title = models.CharField(max_length = 100)
price = models.FloatField()
status = models.CharField(max_length = 100, choices = status_choice)
frequency = models.CharField(max_length = 100)
customers = models.ForeignKey(Customer, related_name = 'subscriptions', blank = True, null = True, on_delete = models.CASCADE)
teas = models.ForeignKey(Tea, blank = True, null = True, on_delete = models.CASCADE)
и Вот фактический serializer.py
class SubscriptionSerializer(serializers.ModelSerializer):
class Meta:
model = Subscription
fields = ['title', 'price', 'status', 'frequency']
class CustomerSerializer(serializers.ModelSerializer):
subscriptions = SubscriptionSerializer(many=True)
class Meta:
model = Customer
fields = ['first_name', 'last_name', 'email', 'address', 'subscriptions']
def create(self, validated_data):
subscriptions_data = validated_data.pop('subscriptions')
customer = Customer.objects.create(**validated_data)
for subscription_data in subscriptions_data:
Subscription.objects.create(customer = customer, **subscription_data)
return customer
Вот полная трассировка стека для ошибки, которую я сейчас получаю:
Traceback (most recent call last):
File "/Users/parkerthomson/take_home_challenges/python/tea_subscription/tea_subscription_api/tests/test_serializers.py", line 77, in setUp
self.customer = Customer.objects.create(**self.customer_attributes)
File "/Users/parkerthomson/take_home_challenges/python/lib/python3.10/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/parkerthomson/take_home_challenges/python/lib/python3.10/site-packages/django/db/models/query.py", line 669, in create
obj = self.model(**kwargs)
File "/Users/parkerthomson/take_home_challenges/python/lib/python3.10/site-packages/django/db/models/base.py", line 562, in __init__
_setattr(self, prop, value)
File "/Users/parkerthomson/take_home_challenges/python/lib/python3.10/site-packages/django/db/models/fields/related_descriptors.py", line 595, in __set__
raise TypeError(
TypeError: Direct assignment to the reverse side of a related set is prohibited. Use subscriptions.set() instead.
Я пытаюсь написать тест, который доказывает, что клиент может быть сериализован для отображения его подписок.
Вы не можете назначить подписки непосредственно в функции Customer.objects.create
- вам нужно задать ее отдельно.
Если вы удалите 'subscriptions'
из self.customer_attributes
, это должно сработать.
Затем вы можете обновить подписку через
Subscription.objects.filter(id=self.subscription_id).update(customers=self.customer)