我正在使用一个模型类Event
,该模型类包含一个可选 ManyToManyField到另一个模型类User
(不同事件可以具有不同的用户),并带有一个工厂类{ {1}}(使用Factory Boy库)和串行器EventFactory
。我相信我已经按照文档进行了工厂制造和序列化,但是却收到错误消息:
ValueError:“ <事件:测试事件>”需要具有字段“ id”的值 在使用这种多对多关系之前。
我知道在链接它们之前必须在ManyToMany中创建这两个模型实例,但是我看不到添加的地方!
有人可以阐明如何通过我尚未使用的模型,工厂男孩和序列化程序正确使用ManyToManyField吗?
这是我的代码:
models.py
EventSerializer
factories.py
@python_2_unicode_compatible
class Event(CommonInfoModel):
users = models.ManyToManyField(User, blank=True, related_name='events')
# other basic fields...
serializers.py
class EventFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.Event
@factory.post_generation
def users(self, create, extracted, **kwargs):
if not create:
# Simple build, do nothing.
return
if extracted:
# A list of users were passed in, use them
# NOTE: This does not seem to be the problem. Setting a breakpoint
# here, this part never even fires
for users in extracted:
self.users.add(users)
test.py
class EventSerializer(BaseModelSerializer):
serialization_title = "Event"
# UserSerializer is a very basic serializer, with no nested
# serializers
users = UserSerializer(required=False, many=True)
class Meta:
model = Event
exclude = ('id',)
感谢您提供的任何帮助!
答案 0 :(得分:1)
关于错误:
似乎丢失的id
是由于使用.build()
而不是.create()
(或仅仅是EventFactory()
)引起的。前者不会保存模型,因此不会获得id
值,而后者会得到(请参考factory docs和model docs)。
我怀疑序列化程序仍然期望对象具有id
,即使多对多关系是可选的,因为如果没有id
,它就不能强制执行潜在的关系。
但是,对于实际任务可能会有更简单的解决方案。上面的方法是一种生成传递到post_api_call()
的POST数据的方法。如果改为手动创建此数据,则不需要工厂和序列化程序。从测试角度来看,显式数据方法甚至可能更好,因为您现在可以看到必须产生预期结果的确切数据。而使用factory和serializer方法时,它在测试中实际使用的内容中要隐含得多。