首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我应该如何构造我的数据库实体与邀请和收件人的电子签名web应用程序在Django?

我应该如何构造我的数据库实体与邀请和收件人的电子签名web应用程序在Django?
EN

Stack Overflow用户
提问于 2021-03-20 20:52:05
回答 1查看 281关注 0票数 2

我有兴趣为我的电子签名web应用程序实现以下要求。

  1. 用户可以创建新的签名契约。该合同可以包括多个用户签署。合同创建者需要提供收件人的电子邮件。每个接收者都将有额外的数据分配,如签名细节、指令等。
  2. 但是,邀请的用户仍然可以是系统中不存在的。这是最棘手的部分。

现在,我的以下实现如下:

  1. I创建一个契约,然后通过电子邮件进行筛选,检查用户是否存在于系统中。如果用户存在,我使用 ContractRecipientEvent通过中间的 table 创建一个多到多实体的,附加的数据被分配给契约。我创建它是多对多的,因为同一个用户可以被分配给多个contracts.
  2. If --用户不在场--我创建了邀请模型,设置了所有收件人的特定数据,并发送了电子邮件。然后注册用户,我使用该电子邮件运行对的11邀请记录的查询,并通过从邀请模型复制数据创建。

我不喜欢我的方法有以下几点:

  1. Many-to-many域我只想为我的合同收件人使用普通的外键,但我不确定应该如何为同一合同分配多个用户?也许我应该创建一个新的模型ContractRecipient,将用户和契约作为外键,但这也是一个多到多的字段?
  2. --我不喜欢将数据从邀请模型复制到ContractRecipientEvent,只需要在用户注册后创建ContractRecipientEvent,因为我需要一个用户实体来创建一个ContractRecipientEvent,它对用户有一个外键。
  3. 的权限结构很难管理。我需要检查包括在合同数据库记录中的所有用户,并检查他们是否被分配到request.

签名后的合同id中。

我正在附加合同列表的最后JSON代码。它可以工作,但我希望有一个正确的模型结构:

代码语言:javascript
复制
{
  "results": [
    {
      "id": 178,
      "is_author": true,
      "title": "ahhzhzh",
      "message_to_all_recipients": null,
      "contract_signing_status": "WAITING_FOR_ME",
      "contract_signing_type": "SIMPLE",
      "contract_signing_date": {
        "start_date": "2010-09-04T14:15:22Z",
        "end_date": "2010-09-04T14:15:22Z"
      },
      "recipients": [
        {
          "message": null,
          "recipient_signing_status": "NOT_SIGNED",
          "recipient_review_status": "NOT_REQUIRED",
          "recipient_action": "SIGN",
          "role": "ADMIN",
          "email": "test2331@gmail.com"
        },
        {
          "message": null,
          "recipient_signing_status": "NOT_SIGNED",
          "recipient_review_status": "NOT_REQUIRED",
          "recipient_action": "SIGN",
          "role": "BASE",
          "email": "test2333@gmail.com"
        }
      ]
    },
    {
      "id": 179,
      "is_author": true,
      "title": "dhhdhd",
      "message_to_all_recipients": null,
      "contract_signing_status": "WAITING_FOR_ME",
      "contract_signing_type": "SIMPLE",
      "contract_signing_date": {
        "start_date": "2010-09-04T14:15:22Z",
        "end_date": "2010-09-04T14:15:22Z"
      },
      "recipients": [
        {
          "message": null,
          "recipient_signing_status": "NOT_SIGNED",
          "recipient_review_status": "NOT_REQUIRED",
          "recipient_action": "SIGN",
          "role": "ADMIN",
          "email": "test123@gmail.com"
        },
        {
          "message": null,
          "recipient_signing_status": "NOT_SIGNED",
          "recipient_review_status": "NOT_REQUIRED",
          "recipient_action": "SIGN",
          "role": "BASE",
          "email": "test233@gmail.com"
        }
      ]
    },
 
  ]
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-24 21:43:19

一个M2M和两个ForeignKeys之间唯一的区别是直通表,但是让我们看看我是否理解。如果我们从以下模型开始:

代码语言:javascript
复制
class User(models.Model):
  email = models.CharField(...)
  ...

class Contract(models.Model):
  user = models.ForeignKey('User', ..., related_name='contracts')
  ...

class Signature(models.Model):
  user = models.ForeignKey('User', ..., related_name='signatures')
  contract = models.ForeignKey('User', ..., related_name='signatures')
  is_signed = models.BooleanField(default=False)
  ...

class Event(models.Model):
  user = models.ForeignKey('User', ..., related_name='events')
  contract = models.ForeignKey('Contract', ..., related_name='events')
  signature = models.ForeignKey('Signature', ..., related_name='events') 
  message = models.CharField(...)
  ...  

现在我们可以做这样的事情:

代码语言:javascript
复制
# get a specific user:
user = User.objects.get(email=<email>)

# get all of the contracts they own:
users_contracts = user.contracts.all() # OR
users_contracts = Contract.objects.filter(user=user)

# get a specific contract:
contract = Contract.objects.get(id=<contract-id>)

# get all the signatures on a contract:
signatures_on_contract = contract.signatures.all() # OR
signatures_on_contract = Signature.objects.filter(contract=contract)

# get all the signatures for a user:
users_signatures = user.signatures.all()

# get all the contracts that the user signed:
users_signed_contracts = Contracts.objects.filter(
  signatures__in = users_signatures,
  signatures__is_signed = True
)

# get all the events on the contract:
events = contract.events.order_by('id')

现在,我们的合同json看起来可以是:

代码语言:javascript
复制
// i.e.: contract with id 7:
{
  'id' : 7,
  'user' : {
    'id' : 2,
    'email' : 'some@email.com'
  },
  'signatures' : [
    {
      'id' : 3,
      'user' : {
        'id' : 2,
        'email' : 'some@email.com'
      },
      'is_signed' : true
    },
    {
      'user' : {
        'id' : 4,
        'email' : 'other@email.com'
      },
      'is_signed' : false
    }
  ],
  'events' : [
    {
      'id' : 6,
      'user' : {
        'id' : 2,
        'email' : 'some@email.com'
      },
      'contract' : {
        'id' : 7
      },
      'signature' : {
        'id' : 3
      },
      'message' : 'signed contract 7'
    }
  ]
}

这里的Event模型可能过于限定,不需要它所拥有的所有ForeignKey关系,但是这样您可以灵活地创建json。

编辑

处理需要签署合同的用户:

代码语言:javascript
复制
# a list of emails:
emails = ['email@1.com', 'email@2.com', ...]

for email in emails:

    # get or create a user:
    user, created = User.objects.get_or_create(email=email)

    # new user logic:
    if created:
        # set temp password
        # redirect users to change password page before signing a doc (can be done elsewhere)
        ...

    # existing user logic:
    else:
        ...

    # create signatures for each user, and add them to the contract:
    signature = Signature.objects.create(user=user, contract=contract)
    ...

编辑2

下面是使用DRF将请求限制到基于对象的Signature表的示例:

views.py

代码语言:javascript
复制
class SignatureViewSet(viewsets.ModelViewSet):

    # override this method to limit access:
    def get_queryset(self):

        # superusers can access all items:
        if self.request.user.is_superuser:
            return self.queryset

        # otherwise, users can only access their own signatures:
        else:
            return self.queryset.filter(user=self.request.user)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66726368

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档