我试图将Jira webhook发布到我使用REST框架在Django中设置的特定模型中。这是模型的代码:
class Webhook(models.Model):
'''issue object with jia metadata'''
event = models.CharField(max_length=256)
hook_id = models.IntegerField(max_length=10)
self = models.CharField(max_length=1024)
issue_key = models.CharField(max_length=12)
fields_summary = models.CharField(max_length=1024)
user_id = models.CharField(max_length=256)
issue_summary = models.CharField(max_length=1024)
issuetype_self = models.CharField(max_length=1024)
issuetype_id = models.IntegerField(max_length=6)
issuetype_name = models.CharField(max_length=48)
reporter = models.CharField(max_length=256)
updated = models.DateTimeField()
created = models.DateTimeField()
description = models.CharField(max_length=1024)
status_description = models.CharField(max_length=48)
status_name = models.CharField(max_length=48)
statuscategory_name = models.CharField(max_length=48)
project_name = models.CharField(max_length=16)
creator = models.CharField(max_length=256)
attachment = models.CharField(max_length=1024, blank=True, null=True)
thumb = models.CharField(max_length=1024, blank=True, null=True)
这里是将发布到Django应用程序的webhook的代码。
{
"webhookEvent": "jira:issue_updated",
"user": {
"self": "https://my.jira-instance.com/rest/api/2/user?username=foo",
"name": "foo",
"emailAddress": "foo@rando_company.com",
"avatarUrls": {
"16x16": "https://my.jira-instance.com/secure/useravatar?size=xsmall&ownerId=foo&avatarId=11062",
"24x24": "https://my.jira-instance.com/secure/useravatar?size=small&ownerId=foo&avatarId=11062",
"32x32": "https://my.jira-instance.com/secure/useravatar?size=medium&ownerId=foo&avatarId=11062",
"48x48": "https://my.jira-instance.com/secure/useravatar?ownerId=foo&avatarId=11062"
},
"displayName": "foo",
"active": true
},
"issue": {
"id": "33062",
"self": "https://my.jira-instance.com/rest/api/2/issue/33062",
"key": "jira-project-key-355",
"fields": {
"summary": "The week ahead",
"progress": {
"progress": 0,
"total": 3600,
"percent": 0
},
"timetracking": {
"originalEstimate": "1h",
"remainingEstimate": "1h",
"originalEstimateSeconds": 3600,
"remainingEstimateSeconds": 3600
},
"customfield_10081": null,
"issuetype": {
"self": "https://my.jira-instance.com/rest/api/2/issuetype/6",
"id": "6",
"description": "",
"iconUrl": "https://my.jira-instance.com/images/icons/issuetypes/story.png",
"name": "Story",
"subtask": false
},
"customfield_10080": "11249",
"timespent": null,
"reporter": {
"self": "https://my.jira-instance.com/rest/api/2/user?username=foo",
"name": "foo",
"emailAddress": "foo@rando_company.com",
"avatarUrls": {
"16x16": "https://my.jira-instance.com/secure/useravatar?size=xsmall&ownerId=foo&avatarId=11062",
"24x24": "https://my.jira-instance.com/secure/useravatar?size=small&ownerId=foo&avatarId=11062",
"32x32": "https://my.jira-instance.com/secure/useravatar?size=medium&ownerId=foo&avatarId=11062",
"48x48": "https://my.jira-instance.com/secure/useravatar?ownerId=foo&avatarId=11062"
},
"displayName": "foo",
"active": true
},
"updated": "2015-02-06T06:58:43.374-0800",
"customfield_10180": null,
"created": "2015-01-02T10:37:27.270-0800",
"priority": {
"self": "https://my.jira-instance.com/rest/api/2/priority/4",
"iconUrl": "https://my.jira-instance.com/images/icons/priorities/minor.png",
"name": "Medium",
"id": "4"
},
"description": null,
"customfield_10002": 20.0,
"issuelinks": [],
"customfield_10004": null,
"customfield_10000": null,
"customfield_11007": null,
"subtasks": [],
"status": {
"self": "https://my.jira-instance.com/rest/api/2/status/10128",
"description": "Staged",
"iconUrl": "https://my.jira-instance.com/images/icons/statuses/generic.png",
"name": "Staged",
"id": "10128",
"statusCategory": {
"self": "https://my.jira-instance.com/rest/api/2/statuscategory/4",
"id": 4,
"key": "indeterminate",
"colorName": "yellow",
"name": "In Progress"
}
},
"labels": [],
"workratio": 0,
"project": {
"self": "https://my.jira-instance.com/rest/api/2/project/10931",
"id": "10931",
"key": "jira-project-key",
"name": "jira-project-key",
"avatarUrls": {
"16x16": "https://my.jira-instance.com/secure/projectavatar?size=xsmall&pid=10931&avatarId=11271",
"24x24": "https://my.jira-instance.com/secure/projectavatar?size=small&pid=10931&avatarId=11271",
"32x32": "https://my.jira-instance.com/secure/projectavatar?size=medium&pid=10931&avatarId=11271",
"48x48": "https://my.jira-instance.com/secure/projectavatar?pid=10931&avatarId=11271"
},
"projectCategory": {
"self": "https://my.jira-instance.com/rest/api/2/projectCategory/10511",
"id": "10511",
"description": "TV Display Projects",
"name": "TV"
}
},
"aggregateprogress": {
"progress": 0,
"total": 3600,
"percent": 0
},
"customfield_11012": null,
"lastViewed": "2015-02-06T06:58:43.360-0800",
"components": [],
"customfield_11010": null,
"customfield_10010": null,
"comment": {
"startAt": 0,
"maxResults": 0,
"total": 0,
"comments": []
},
"timeoriginalestimate": 3600,
"customfield_11014": null,
"customfield_10681": null,
"votes": {
"self": "https://my.jira-instance.com/rest/api/2/issue/jira-project-key-355/votes",
"votes": 0,
"hasVoted": false
},
"fixVersions": [],
"resolution": null,
"resolutiondate": null,
"creator": {
"self": "https://my.jira-instance.com/rest/api/2/user?username=foo",
"name": "foo",
"emailAddress": "foo@rando_company.com",
"avatarUrls": {
"16x16": "https://my.jira-instance.com/secure/useravatar?size=xsmall&ownerId=foo&avatarId=11062",
"24x24": "https://my.jira-instance.com/secure/useravatar?size=small&ownerId=foo&avatarId=11062",
"32x32": "https://my.jira-instance.com/secure/useravatar?size=medium&ownerId=foo&avatarId=11062",
"48x48": "https://my.jira-instance.com/secure/useravatar?ownerId=foo&avatarId=11062"
},
"displayName": "foo",
"active": true
},
"customfield_10880": null,
"aggregatetimeoriginalestimate": 3600,
"customfield_10884": null,
"customfield_10883": null,
"customfield_10881": null,
"duedate": null,
"customfield_10020": null,
"customfield_10782": null,
"customfield_10781": "2015-01-30",
"customfield_10780": null,
"watches": {
"self": "https://my.jira-instance.com/rest/api/2/issue/jira-project-key-355/watchers",
"watchCount": 1,
"isWatching": true
},
"worklog": {
"startAt": 0,
"maxResults": 20,
"total": 0,
"worklogs": []
},
"assignee": {
"self": "https://my.jira-instance.com/rest/api/2/user?username=foo",
"name": "foo",
"emailAddress": "foo@rando_company.com",
"avatarUrls": {
"16x16": "https://my.jira-instance.com/secure/useravatar?size=xsmall&ownerId=foo&avatarId=11062",
"24x24": "https://my.jira-instance.com/secure/useravatar?size=small&ownerId=foo&avatarId=11062",
"32x32": "https://my.jira-instance.com/secure/useravatar?size=medium&ownerId=foo&avatarId=11062",
"48x48": "https://my.jira-instance.com/secure/useravatar?ownerId=foo&avatarId=11062"
},
"displayName": "foo",
"active": true
},
"attachment": [{
"self": "https://my.jira-instance.com/rest/api/2/attachment/13041",
"id": "13041",
"filename": "jan_5.jpg",
"author": {
"self": "https://my.jira-instance.com/rest/api/2/user?username=foo",
"name": "foo",
"emailAddress": "foo@rando_company.com",
"avatarUrls": {
"16x16": "https://my.jira-instance.com/secure/useravatar?size=xsmall&ownerId=foo&avatarId=11062",
"24x24": "https://my.jira-instance.com/secure/useravatar?size=small&ownerId=foo&avatarId=11062",
"32x32": "https://my.jira-instance.com/secure/useravatar?size=medium&ownerId=foo&avatarId=11062",
"48x48": "https://my.jira-instance.com/secure/useravatar?ownerId=foo&avatarId=11062"
},
"displayName": "foo",
"active": true
},
"created": "2015-01-02T10:37:37.802-0800",
"size": 143252,
"mimeType": "image/jpeg",
"content": "https://my.jira-instance.com/secure/attachment/13041/jan_5.jpg",
"thumbnail": "https://my.jira-instance.com/secure/thumbnail/13041/_thumb_13041.png"
}, {
"self": "https://my.jira-instance.com/rest/api/2/attachment/13250",
"id": "13250",
"filename": "ThisWeek_Feb2.jpg",
"author": {
"self": "https://my.jira-instance.com/rest/api/2/user?username=foo",
"name": "foo",
"emailAddress": "foo@rando_company.com",
"avatarUrls": {
"16x16": "https://my.jira-instance.com/secure/useravatar?size=xsmall&ownerId=foo&avatarId=11062",
"24x24": "https://my.jira-instance.com/secure/useravatar?size=small&ownerId=foo&avatarId=11062",
"32x32": "https://my.jira-instance.com/secure/useravatar?size=medium&ownerId=foo&avatarId=11062",
"48x48": "https://my.jira-instance.com/secure/useravatar?ownerId=foo&avatarId=11062"
},
"displayName": "foo",
"active": true
},
"created": "2015-01-30T10:31:40.641-0800",
"size": 274703,
"mimeType": "image/jpeg",
"content": "https://my.jira-instance.com/secure/attachment/13250/ThisWeek_Feb2.jpg",
"thumbnail": "https://my.jira-instance.com/secure/thumbnail/13250/_thumb_13250.png"
}, {
"self": "https://my.jira-instance.com/rest/api/2/attachment/13087",
"id": "13087",
"filename": "ThisWeek_jan12.jpg",
"author": {
"self": "https://my.jira-instance.com/rest/api/2/user?username=foo",
"name": "foo",
"emailAddress": "foo@rando_company.com",
"avatarUrls": {
"16x16": "https://my.jira-instance.com/secure/useravatar?size=xsmall&ownerId=foo&avatarId=11062",
"24x24": "https://my.jira-instance.com/secure/useravatar?size=small&ownerId=foo&avatarId=11062",
"32x32": "https://my.jira-instance.com/secure/useravatar?size=medium&ownerId=foo&avatarId=11062",
"48x48": "https://my.jira-instance.com/secure/useravatar?ownerId=foo&avatarId=11062"
},
"displayName": "foo",
"active": true
},
"created": "2015-01-12T08:18:40.652-0800",
"size": 121908,
"mimeType": "image/jpeg",
"content": "https://my.jira-instance.com/secure/attachment/13087/ThisWeek_jan12.jpg",
"thumbnail": "https://my.jira-instance.com/secure/thumbnail/13087/_thumb_13087.png"
}, {
"self": "https://my.jira-instance.com/rest/api/2/attachment/13147",
"id": "13147",
"filename": "ThisWeek_jan19.png",
"author": {
"self": "https://my.jira-instance.com/rest/api/2/user?username=foo",
"name": "foo",
"emailAddress": "foo@rando_company.com",
"avatarUrls": {
"16x16": "https://my.jira-instance.com/secure/useravatar?size=xsmall&ownerId=foo&avatarId=11062",
"24x24": "https://my.jira-instance.com/secure/useravatar?size=small&ownerId=foo&avatarId=11062",
"32x32": "https://my.jira-instance.com/secure/useravatar?size=medium&ownerId=foo&avatarId=11062",
"48x48": "https://my.jira-instance.com/secure/useravatar?ownerId=foo&avatarId=11062"
},
"displayName": "foo",
"active": true
},
"created": "2015-01-19T09:40:58.930-0800",
"size": 2339087,
"mimeType": "image/png",
"content": "https://my.jira-instance.com/secure/attachment/13147/ThisWeek_jan19.png",
"thumbnail": "https://my.jira-instance.com/secure/thumbnail/13147/_thumb_13147.png"
}, {
"self": "https://my.jira-instance.com/rest/api/2/attachment/13189",
"id": "13189",
"filename": "ThisWeek-Jan26.jpg",
"author": {
"self": "https://my.jira-instance.com/rest/api/2/user?username=foo",
"name": "foo",
"emailAddress": "foo@rando_company.com",
"avatarUrls": {
"16x16": "https://my.jira-instance.com/secure/useravatar?size=xsmall&ownerId=foo&avatarId=11062",
"24x24": "https://my.jira-instance.com/secure/useravatar?size=small&ownerId=foo&avatarId=11062",
"32x32": "https://my.jira-instance.com/secure/useravatar?size=medium&ownerId=foo&avatarId=11062",
"48x48": "https://my.jira-instance.com/secure/useravatar?ownerId=foo&avatarId=11062"
},
"displayName": "foo",
"active": true
},
"created": "2015-01-23T09:55:32.198-0800",
"size": 138201,
"mimeType": "image/jpeg",
"content": "https://my.jira-instance.com/secure/attachment/13189/ThisWeek-Jan26.jpg",
"thumbnail": "https://my.jira-instance.com/secure/thumbnail/13189/_thumb_13189.png"
}],
"aggregatetimeestimate": 3600,
"versions": [],
"timeestimate": 3600,
"aggregatetimespent": null,
"customfield_10070": null
}
},
"changelog": {
"id": "219580",
"items": [{
"field": "status",
"fieldtype": "jira",
"from": "10127",
"fromString": "Submitted",
"to": "10128",
"toString": "Staged"
}]
},
"timestamp": 1423234723378
}
我的问题是,在POST负载中削减数据以适应我的模型的首选方法是什么?我应该重构我的模型以匹配webhook JSON吗?或者我应该使用预保存挂钩来解析我想要的属性,然后返回解析后的有效负载?或者我应该覆盖webhook对象上的save方法来解析我需要的数据然后只保存我需要的位?
我尝试创建一个简单的序列化程序,只初始化几个字段并将整个有效负载扔到它上面以查看哪些字符串,但没有任何内容被保存。
答案 0 :(得分:2)
这实际上取决于您尝试对收集的数据做些什么。 如果仅用于数据存储目的,创建映射类将是更好的解决方案。
class JiraWebhookMapper(object):
def map(data):
return {'user_id': data.get("user").get("id") ....}
mapped_data = JiraWebhookMapper().map(response.content)
WebHook.objects.create(**mapped_data)