问题描述
我有兴趣为我的电子签名Web应用程序实现以下要求.
I am interested in implementing the following requirements for my e-signature web application.
- 用户可以创建新的签订合同.该合同可以包括多个用户进行签名.合同创建者需要提供收件人的电子邮件.每个收件人都会分配其他数据,例如签名详细信息,说明等.
- 但是,被邀请的用户仍然可以不出现在系统中.这是最棘手的部分.
- A user can create a new signing contract. That contract can include multiple users to sign. The contract creator needs to provide emails of the recipients. Every recipient will have additional data assigned, like signing details, instructions and etc.
- However, the invited user can still be not present in the system. This is the trickest part.
现在我的以下实现如下:
Right now my following implementation is the following:
- 我创建合同,然后通过电子邮件进行过滤来检查系统中是否存在用户.如果用户存在,我将使用通过中间 表以及其他数据,使用创建一个多对多实体ContractRecipientEvent,.我创建了很多对它,因为可以将同一用户分配给多个合同.
- 如果用户不存在,我将创建邀请模型,设置所有收件人的特定数据,然后发送电子邮件.然后注册用户,我通过复制来自邀请模型的数据来运行带有该电子邮件的所有邀请记录的查询并创建ContractRecipientEvent.
- I create a contract, then check if a user is present in the system by making a filter by email. If the user exists, I create a many-to-many entity ContractRecipientEvent using through intermediate table with additional data, which is assigned to the contract. I create it many-to-many because the same user can be assigned to multiple contracts.
- If the user is not present I create the Invitation model, set all recipient's specific data, and send an email. Then the user is registered, I run the query of all Invitations records with that email and create ContractRecipientEvent, by copying data from the Invitation model.
我不喜欢以下方法:
- 多对多字段.我只想为我的合同接收者使用简单的外键,但是我不确定如何将多个用户分配给同一个合同?也许我应该使用用户和合同作为外键创建一个新的ContractRecipient模型,但这也是一个多对多字段?
- 我不喜欢这样,我需要将数据从邀请模型复制到ContractRecipientEvent ,并且仅在用户注册后才创建ContractRecipientEvent,因为我需要一个用户实体来创建ContractRecipientEvent,对用户有外键.
- 权限结构难以管理.我需要检查所有包含在合同数据库记录中的用户,并检查是否将他们分配给用于签署POST请求的合同ID.
- Many-to-many field. I would like to just use plain Foreign keys for my contract recipients, but I am unsure how should I assign multiple users to the same contract? Perhaps I should create a new model ContractRecipient with the user and contract as foreign keys, but that is a many-to-many field also?
- I don't like that I need to copy data from the Invitation model to the ContractRecipientEvent and only create ContractRecipientEvent after the user is registered, because I need a user entity to create a ContractRecipientEvent, which has a foreign key to the user.
- The permission structure is difficult to manage. I need to check all the users, who are included in the contract database record, and check if they are assigned to the contract id, they are using for the signing POST request.
我附上了合同清单的最终JSON代码.它可以工作,但是我想有一个正确的模型结构:
I am attaching my final JSON code of the contract list. It works, but I would like to have a correct models structure:
{
"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": "[email protected]"
},
{
"message": null,
"recipient_signing_status": "NOT_SIGNED",
"recipient_review_status": "NOT_REQUIRED",
"recipient_action": "SIGN",
"role": "BASE",
"email": "[email protected]"
}
]
},
{
"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": "[email protected]"
},
{
"message": null,
"recipient_signing_status": "NOT_SIGNED",
"recipient_review_status": "NOT_REQUIRED",
"recipient_action": "SIGN",
"role": "BASE",
"email": "[email protected]"
}
]
},
]
}
推荐答案
M2M和两个ForeignKey之间的唯一区别是穿透表,但让我们看看是否可以理解.如果我们从以下模型开始怎么办:
Well the only difference between a M2M and two ForeignKeys is the through table but let's see if I understand. What if we started with the following models:
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(...)
...
现在我们可以做类似的事情:
Now we can do things like:
# 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看起来可能像这样:
Now our contract json can look something like:
// i.e.: contract with id 7:
{
'id' : 7,
'user' : {
'id' : 2,
'email' : '[email protected]'
},
'signatures' : [
{
'id' : 3,
'user' : {
'id' : 2,
'email' : '[email protected]'
},
'is_signed' : true
},
{
'user' : {
'id' : 4,
'email' : '[email protected]'
},
'is_signed' : false
}
],
'events' : [
{
'id' : 6,
'user' : {
'id' : 2,
'email' : '[email protected]'
},
'contract' : {
'id' : 7
},
'signature' : {
'id' : 3
},
'message' : 'signed contract 7'
}
]
}
这里的 Event
模型可能是合格的,并且不需要它具有的所有 ForeignKey
关系,但是通过这种方式,您可以灵活地创建json.
The Event
model here is perhaps overqualified and doesn't need all the ForeignKey
relations it has, but this way you can flexibly create your json.
处理需要签订合同的用户:
Handling users who need to sign a contract:
# a list of emails:
emails = ['[email protected]', '[email protected]', ...]
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
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)
这篇关于如何在Django中使用邀请和收件人构造数据库实体以进行电子签名Web应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!