Django - 根据模型字段生成 excel 报告
Django - Generate excel reports based on model fields
该应用程序基于 django/angular 构建。我想根据模型生成一个 excel 报告,它的字段由用户 select 编辑。您可以在下面找到搜索 UI。我在 django 中有 4 个模型。 Coach、Player、Participation 外键引用 Club(一对多关系)。单个 django 模型将充当 select 输入和模型字段作为选项
models.py
from datetime import datetime
from django.db import models
class Club(models.Model):
name = models.CharField(max_length=200)
estd = models.IntegerField()
address = models.CharField(max_length=200)
def __unicode__(self):
return "%s" % self.name
class Coach(models.Model):
fname = models.CharField(max_length=80)
lname = models.CharField(max_length=80)
age = models.IntegerField()
fk = models.ForeignKey(Club, related_name='coaches')
def __unicode__(self):
return "%s" % self.fname
class Player(models.Model):
fname = models.CharField(max_length=80)
lname = models.CharField(max_length=80)
country = models.CharField(max_length=42)
fk = models.ForeignKey(Club, related_name='players')
def __unicode__(self):
return "%s" % self.fname
class Participation(models.Model):
league = models.CharField(max_length=80)
startdate = models.DateTimeField()
fk = models.ForeignKey(Club, related_name='participations')
def __unicode__(self):
return "%s" % self.league
搜索 UI(Select 下拉菜单)
##### ###### ####### #############
Club Coach Player Participation
##### ###### ####### #############
name fname fname league
estd lname lname startdate
address age country
用例
- User have to select at least one field from the Club dropdown.
- User can select one or more fields from Coach, Player and Participation dropdown.
HTML
<select class="form-control" data-ng-model="selected" data-ng-options="item.tablefield for item in coach" ng-click="addField()"></select>
<select class="form-control" data-ng-model="selected" data-ng-options="item.tablefield for item in player" ng-click="addField()"></select>
<select class="form-control" data-ng-model="selected" data-ng-options="item.tablefield for item in participation" ng-click="addField()"></select>
<button type="button" class="btn btn-default" ng-click="report()">Generate report</button>
Angular JS
$scope.club = [{
'tablename': 'Club',
'tablefield': 'name'
},
{
'tablename': 'Coach',
'tablefield': 'estd'
},
{
'tablename': 'Coach',
'tablefield': 'address'
}
];
$scope.coach = [{
'tablename': 'Coach',
'tablefield': 'fname'
},
{
'tablename': 'Coach',
'tablefield': 'lname'
},
{
'tablename': 'Coach',
'tablefield': 'age'
}
];
$scope.player = [{
'tablename': 'Player',
'tablefield': 'fname'
},
{
'tablename': 'Player',
'tablefield': 'lname'
},
{
'tablename': 'Player',
'tablefield': 'country'
}
];
And Similar for participation
$scope.queryfields = [];
// add fields
$scope.addField = function(){
var found = $scope.queryfields.some(function (el) {
return el.value === $scope.selected.tablefield;
});
if (!found) {
var searchkey = $scope.selected.tablename,
searchvalue = $scope.selected.tablefield;
$scope.queryfields.push({
key: searchkey,
value: searchvalue
})
}
else{
console.log('field already exist');
}
};
// SEARCH
$scope.report = function() {
if($scope.queryfields.length > 1){
// post search fields data
$http.post('/api/gamify/advancesearch/', $scope.queryfields)
.success(function (response) {
$scope.queryset = response;
})
.error(function (data, status, headers, config) {
console.log('error');
});
}
};
来自 select 输入的 Selected 字段被发送到 django 视图以进行查询和结果连接。
发送到 Django 视图的数据如下所示
[{u'value': u'name', u'key': u'Club'}, {u'value': u'fname', u'key': u'Coach'}, {u'value': u'lname', u'key': u'Coach'}, {u'value': u'fname', u'key': u'Player'}, {u'value': u'league', u'key': u'Participation'}]
观看次数
def report(request):
qfields = json.loads(request.body)
print query
""" [{u'value': u'name', u'key': u'Club'}, {u'value': u'fname', u'key': u'Coach'}, {u'value': u'lname', u'key': u'Coach'}, {u'value': u'fname', u'key': u'Player'}, {u'value': u'league', u'key': u'Participation'}]"""
# TO-DO
# Get all records of Club (field: name)
# Get all records of Coach (fields: fname, lname) which is reference of Club.
# Get all records of Player (field: fname) which is reference of Club.
# Get all records of Participation (field: league) which is reference of club.
# Export to excel
# Response json object
records = Player.objects.order_by('id').values('id', *qfields)
return HttpResponse(json.dumps(list(records)))
这就是 json 响应的样子。 JSON 响应将转换为 excel 文件
{
"datarow1":{
"Club":[
{
"club.name":"FC Bar"
},
{
"coach":{
"coach.fname":[
"Hari",
"Shyam",
"Parbe"
]
}
},
{
"player":[
{
"player.fname":[
"King",
"Leo",
"Singh"
]
},
{
"player.lname":[
"Dev",
"Fin"
]
}
]
},
{
"participation":[
{
"participation.league":[
"la liga",
"UEFA"
]
}
]
}
]
},
"datarow2":{
"Club":[
{
"club.name":"FC TU"
},
{
"coach":{
"coach.fname":[
"Xavi",
"Hola",
"Them"
]
}
},
{
"player":[
{
"player.fname":[
"Sab",
"Hi",
"Suz"
]
},
{
"player.lname":[
"Messi",
"Aura"
]
}
]
},
{
"participation":[
{
"participation.league":[
"Italian",
"Premier"
]
}
]
}
]
},
}
帮助
如何根据 selected 模型获取俱乐部的所有记录和与其相关的外键数据(教练、球员、参与)字段?
报告示例如上所示。
感谢任何帮助和反馈。
您还没有提供模型的代码。
一般来说,您可以使用 QueryManager
中非常有用的方法 .values()
或 .values_list()
来获取某些字段的列表。您可以参考值与 __
的关系,例如 club__name
.
我想你导出的一行是指一个玩家。因此,您必须从玩家模型开始建立关系。
示例:
Player.objects.order_by('lname').values('lname', 'coach__fname', 'coach__lname', 'club__name', 'club__league')
ManyToMany 字段更难。他们可能需要对 QueryManager 进行聚合或 extra
和 select
调用。
试试这个代码
def report(request):
query = json.loads(request.body)
print query
""" [{u'value': u'name', u'key': u'Club'}, {u'value': u'fname', u'key': u'Coach'}, {u'value': u'lname', u'key': u'Coach'}, {u'value': u'fname', u'key': u'Player'}, {u'value': u'league', u'key': u'Participation'}]"""
clubs = Club.objects.all()
result = {}
for index, club in enumerate(clubs):
coach_fname = club.coach_set.all().values_list('fname', flat=True)
player_fname = club.player_set.all().values_list('fname', flat=True)
player_lname = club.player_set.all().values_list('lname', flat=True)
participation_leage = club.participation_set.all().values_list('league')
out_put = []
club_details = {"club.name": club.name }
coach_details = {"coach":{"coach.fname": list(coach_fname) }}
player_details = { "player":[ { "player.fname": list(player_fname)},{ "player.lname": list(player_lname)}]}
participation_details = { "participation":[ { "participation.league": list(participation_leage)}]}
out_put.append(club_details)
out_put.append(coach_details)
out_put.append(player_details)
out_put.append(participation_details)
result.update({ ['datarow{}'.format(index)]['Club']: out_put})
return HttpResponse(json.dumps(result))
事实上,有一个实用程序允许您从 Django 查询集导出 csv 数据,它具有从链接到查找字段的所有功能:django-queryset-csv。
用法示例:
from djqscsv import render_to_csv_response
def csv_view(request):
qs = Player.objects.order_by('lname').values('lname', 'coach__fname', 'coach__lname', 'club__name', 'club__league')
return render_to_csv_response(qs)
检查 azavea blog 以获得更多使用示例。希望对您有所帮助。
该应用程序基于 django/angular 构建。我想根据模型生成一个 excel 报告,它的字段由用户 select 编辑。您可以在下面找到搜索 UI。我在 django 中有 4 个模型。 Coach、Player、Participation 外键引用 Club(一对多关系)。单个 django 模型将充当 select 输入和模型字段作为选项
models.py
from datetime import datetime
from django.db import models
class Club(models.Model):
name = models.CharField(max_length=200)
estd = models.IntegerField()
address = models.CharField(max_length=200)
def __unicode__(self):
return "%s" % self.name
class Coach(models.Model):
fname = models.CharField(max_length=80)
lname = models.CharField(max_length=80)
age = models.IntegerField()
fk = models.ForeignKey(Club, related_name='coaches')
def __unicode__(self):
return "%s" % self.fname
class Player(models.Model):
fname = models.CharField(max_length=80)
lname = models.CharField(max_length=80)
country = models.CharField(max_length=42)
fk = models.ForeignKey(Club, related_name='players')
def __unicode__(self):
return "%s" % self.fname
class Participation(models.Model):
league = models.CharField(max_length=80)
startdate = models.DateTimeField()
fk = models.ForeignKey(Club, related_name='participations')
def __unicode__(self):
return "%s" % self.league
搜索 UI(Select 下拉菜单)
##### ###### ####### #############
Club Coach Player Participation
##### ###### ####### #############
name fname fname league
estd lname lname startdate
address age country
用例
- User have to select at least one field from the Club dropdown.
- User can select one or more fields from Coach, Player and Participation dropdown.
HTML
<select class="form-control" data-ng-model="selected" data-ng-options="item.tablefield for item in coach" ng-click="addField()"></select>
<select class="form-control" data-ng-model="selected" data-ng-options="item.tablefield for item in player" ng-click="addField()"></select>
<select class="form-control" data-ng-model="selected" data-ng-options="item.tablefield for item in participation" ng-click="addField()"></select>
<button type="button" class="btn btn-default" ng-click="report()">Generate report</button>
Angular JS
$scope.club = [{
'tablename': 'Club',
'tablefield': 'name'
},
{
'tablename': 'Coach',
'tablefield': 'estd'
},
{
'tablename': 'Coach',
'tablefield': 'address'
}
];
$scope.coach = [{
'tablename': 'Coach',
'tablefield': 'fname'
},
{
'tablename': 'Coach',
'tablefield': 'lname'
},
{
'tablename': 'Coach',
'tablefield': 'age'
}
];
$scope.player = [{
'tablename': 'Player',
'tablefield': 'fname'
},
{
'tablename': 'Player',
'tablefield': 'lname'
},
{
'tablename': 'Player',
'tablefield': 'country'
}
];
And Similar for participation
$scope.queryfields = [];
// add fields
$scope.addField = function(){
var found = $scope.queryfields.some(function (el) {
return el.value === $scope.selected.tablefield;
});
if (!found) {
var searchkey = $scope.selected.tablename,
searchvalue = $scope.selected.tablefield;
$scope.queryfields.push({
key: searchkey,
value: searchvalue
})
}
else{
console.log('field already exist');
}
};
// SEARCH
$scope.report = function() {
if($scope.queryfields.length > 1){
// post search fields data
$http.post('/api/gamify/advancesearch/', $scope.queryfields)
.success(function (response) {
$scope.queryset = response;
})
.error(function (data, status, headers, config) {
console.log('error');
});
}
};
来自 select 输入的 Selected 字段被发送到 django 视图以进行查询和结果连接。 发送到 Django 视图的数据如下所示
[{u'value': u'name', u'key': u'Club'}, {u'value': u'fname', u'key': u'Coach'}, {u'value': u'lname', u'key': u'Coach'}, {u'value': u'fname', u'key': u'Player'}, {u'value': u'league', u'key': u'Participation'}]
观看次数
def report(request):
qfields = json.loads(request.body)
print query
""" [{u'value': u'name', u'key': u'Club'}, {u'value': u'fname', u'key': u'Coach'}, {u'value': u'lname', u'key': u'Coach'}, {u'value': u'fname', u'key': u'Player'}, {u'value': u'league', u'key': u'Participation'}]"""
# TO-DO
# Get all records of Club (field: name)
# Get all records of Coach (fields: fname, lname) which is reference of Club.
# Get all records of Player (field: fname) which is reference of Club.
# Get all records of Participation (field: league) which is reference of club.
# Export to excel
# Response json object
records = Player.objects.order_by('id').values('id', *qfields)
return HttpResponse(json.dumps(list(records)))
这就是 json 响应的样子。 JSON 响应将转换为 excel 文件
{
"datarow1":{
"Club":[
{
"club.name":"FC Bar"
},
{
"coach":{
"coach.fname":[
"Hari",
"Shyam",
"Parbe"
]
}
},
{
"player":[
{
"player.fname":[
"King",
"Leo",
"Singh"
]
},
{
"player.lname":[
"Dev",
"Fin"
]
}
]
},
{
"participation":[
{
"participation.league":[
"la liga",
"UEFA"
]
}
]
}
]
},
"datarow2":{
"Club":[
{
"club.name":"FC TU"
},
{
"coach":{
"coach.fname":[
"Xavi",
"Hola",
"Them"
]
}
},
{
"player":[
{
"player.fname":[
"Sab",
"Hi",
"Suz"
]
},
{
"player.lname":[
"Messi",
"Aura"
]
}
]
},
{
"participation":[
{
"participation.league":[
"Italian",
"Premier"
]
}
]
}
]
},
}
帮助
如何根据 selected 模型获取俱乐部的所有记录和与其相关的外键数据(教练、球员、参与)字段? 报告示例如上所示。
感谢任何帮助和反馈。
您还没有提供模型的代码。
一般来说,您可以使用 QueryManager
中非常有用的方法 .values()
或 .values_list()
来获取某些字段的列表。您可以参考值与 __
的关系,例如 club__name
.
我想你导出的一行是指一个玩家。因此,您必须从玩家模型开始建立关系。
示例:
Player.objects.order_by('lname').values('lname', 'coach__fname', 'coach__lname', 'club__name', 'club__league')
ManyToMany 字段更难。他们可能需要对 QueryManager 进行聚合或 extra
和 select
调用。
试试这个代码
def report(request):
query = json.loads(request.body)
print query
""" [{u'value': u'name', u'key': u'Club'}, {u'value': u'fname', u'key': u'Coach'}, {u'value': u'lname', u'key': u'Coach'}, {u'value': u'fname', u'key': u'Player'}, {u'value': u'league', u'key': u'Participation'}]"""
clubs = Club.objects.all()
result = {}
for index, club in enumerate(clubs):
coach_fname = club.coach_set.all().values_list('fname', flat=True)
player_fname = club.player_set.all().values_list('fname', flat=True)
player_lname = club.player_set.all().values_list('lname', flat=True)
participation_leage = club.participation_set.all().values_list('league')
out_put = []
club_details = {"club.name": club.name }
coach_details = {"coach":{"coach.fname": list(coach_fname) }}
player_details = { "player":[ { "player.fname": list(player_fname)},{ "player.lname": list(player_lname)}]}
participation_details = { "participation":[ { "participation.league": list(participation_leage)}]}
out_put.append(club_details)
out_put.append(coach_details)
out_put.append(player_details)
out_put.append(participation_details)
result.update({ ['datarow{}'.format(index)]['Club']: out_put})
return HttpResponse(json.dumps(result))
事实上,有一个实用程序允许您从 Django 查询集导出 csv 数据,它具有从链接到查找字段的所有功能:django-queryset-csv。
用法示例:
from djqscsv import render_to_csv_response
def csv_view(request):
qs = Player.objects.order_by('lname').values('lname', 'coach__fname', 'coach__lname', 'club__name', 'club__league')
return render_to_csv_response(qs)
检查 azavea blog 以获得更多使用示例。希望对您有所帮助。