Django 更好的OOP实践是使用关系映射向类添加方法

Django 更好的OOP实践是使用关系映射向类添加方法,django,factory-boy,Django,Factory Boy,假设下面的示例代码结构 # Returns a region class RegionFactory: ..... # Returns a user class UserFactory(): ..... # Assigns a user with a permission against specific region class RegionUserPermissionFactory(): user = UserFactory() permi

假设下面的示例代码结构

# Returns a region
class RegionFactory:
      .....

# Returns a user
class UserFactory():
      .....

# Assigns a user with a permission against specific region
class RegionUserPermissionFactory():
      user = UserFactory()
      permission = PermissionFactory()
      .... 
现在我想有一个方法,允许分配“用户区域权限”,我认为这个方法非常适合UserFactory,因为它类似于一个真实的世界级模板

 def add_user_domain_permission(permission_options, domain):
     ....
     (Invokes RegionUserPermissionFactory to create objects relevant to
      the user)
     ....
2019年9月25日编辑
在父类中包含与RegionUserPermission相关的方法是否更好?在我当前的代码库中,还有几个类包含用户对象,将它们添加到UserFactory中是否是更好的OOP实践?它是否违反抽象封装概念?

工厂男孩的想法是将工厂定义为与您的测试用例相关;应该定义属性和参数集,以便在编写测试时提供简单的API。 该库侧重于提供可读和可维护的测试,而不是严格遵循OOP原则;)

在您的示例中,如果一些测试需要一个简单的用户,而其他测试需要将其附加到特定的区域,那么您可以添加第二个专用于该用例的工厂,例如
RegionalizedUserFactory

class RegionalizedUserFactory(UserFactory):
    class Params:
        # Tests would call RegionalizedUserFactory(region_code='xxx')
        # Setting this as a `Param` means that the `region_code` field won't be passed
        # to User.objects.create(...)
        region_code = 'asia'

    add_user_permission = factory.RelatedFactory(
        # Once the `User` is created, call UserPermissionFactory(user=the_user, ...)
        UserPermissionFactory, 'user',

        # And use this factory's region_code attribute as the code for RegionFactory
        permission__region__code=factory.SelfAttribute('....region_code'),
    )
其用途如下:

>>> UserFactory()  # No region perms
<User: John Doe, perms=[]>
>>> RegionalizedUserFactory()   # Default on asia
<User: John Doe, perms=[<Permission: level=admin, region=<Region: asia>>]>
>>> RegionalizedUserFactory(region_code='mars')   # Custom region
<User: John Doe, perms=[<Permission: level=admin, region=<Region: mars>>]>
第二家工厂:

>>> UserFactory()  # No region_code => no perms
<User: John Doe, perms=[]>
>>> UserFactory(region_code='asia')
<User: John Doe, perms=[<Permission: level=admin, region=<Region: asia>>]>
>>UserFactory()#无区域_代码=>无烫发
>>>用户工厂(地区代码='asia')

factory\u boy的思想是定义与您的测试用例相关的工厂;应该定义属性和参数集,以便在编写测试时提供简单的API。 该库侧重于提供可读和可维护的测试,而不是严格遵循OOP原则;)

在您的示例中,如果一些测试需要一个简单的用户,而其他测试需要将其附加到特定的区域,那么您可以添加第二个专用于该用例的工厂,例如
RegionalizedUserFactory

class RegionalizedUserFactory(UserFactory):
    class Params:
        # Tests would call RegionalizedUserFactory(region_code='xxx')
        # Setting this as a `Param` means that the `region_code` field won't be passed
        # to User.objects.create(...)
        region_code = 'asia'

    add_user_permission = factory.RelatedFactory(
        # Once the `User` is created, call UserPermissionFactory(user=the_user, ...)
        UserPermissionFactory, 'user',

        # And use this factory's region_code attribute as the code for RegionFactory
        permission__region__code=factory.SelfAttribute('....region_code'),
    )
其用途如下:

>>> UserFactory()  # No region perms
<User: John Doe, perms=[]>
>>> RegionalizedUserFactory()   # Default on asia
<User: John Doe, perms=[<Permission: level=admin, region=<Region: asia>>]>
>>> RegionalizedUserFactory(region_code='mars')   # Custom region
<User: John Doe, perms=[<Permission: level=admin, region=<Region: mars>>]>
第二家工厂:

>>> UserFactory()  # No region_code => no perms
<User: John Doe, perms=[]>
>>> UserFactory(region_code='asia')
<User: John Doe, perms=[<Permission: level=admin, region=<Region: asia>>]>
>>UserFactory()#无区域_代码=>无烫发
>>>用户工厂(地区代码='asia')

您想创建一个方法来向用户添加特定的权限,您想知道这个方法应该是这三个类中的哪一个,对吗?我没有发现将它放入UserFactory类会违反任何规定,而且它看起来是合乎逻辑的。然而,由于您主要展示的是伪代码,而我们并不真正知道您希望在整个程序中实现什么,因此可能很难为您提供更多帮助。我建议提供更多关于你的课程如何运作以及你想用它们做什么的信息,这样我们可以更好地帮助你。谢谢你。我将编辑该问题以包含更精确的信息。您想创建一个方法来向用户添加特定权限,并且您想知道该方法应该属于这三个类中的哪一个,对吗?我没有发现将它放入UserFactory类会违反任何规定,而且它看起来是合乎逻辑的。然而,由于您主要展示的是伪代码,而我们并不真正知道您希望在整个程序中实现什么,因此可能很难为您提供更多帮助。我建议提供更多关于你的课程如何运作以及你想用它们做什么的信息,这样我们可以更好地帮助你。谢谢你。我将编辑这个问题以包含更精确的信息。这非常有用。谢谢,它真的很有用。谢谢你,希勒诺