Django-создание отчетов excel на основе полей модели

приложение построено на Джанго/угловой. Я хочу создать отчет excel на основе модели и полей, выбранных пользователями. Вы можете найти поиск UI ниже. У меня есть 4 модели в django. главный тренер, плеер, участия которые имеют ссылку на внешний ключ клуб (один ко многим). Индивидуальная модель django будет действовать как поля ввода и модели в качестве опции

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 (выберите раскрывающийся список)

#####       ######      #######     #############
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>

угловой 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');
            });
        }
    };

выбранные поля из выбранных входных данных отправляются в представления 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"
                        ]
                    }
                ]
            }
        ]
    }, 

}

помогите

как я могу получить все записи клубов и данные внешнего ключа (тренер, игрок, участие), связанные с ним на основе выбранные поля модели? Пример отчета приведен выше.

помощь и обратная связь являются оцененный.

3 ответов


вы не указали код модели.

в общем, вы можете получить список определенных полей, используя очень полезные методы .values() или .values_list() на QueryManager. Вы можете ссылаться на отношение значений с __ как club__name.

Я полагаю, что одна строка в вашем экспорте относится к одному игроку. Таким образом, вам нужно будет установить отношение, начиная с модели игрока.

пример:

Player.objects.order_by('lname').values('lname', 'coach__fname', 'coach__lname', 'club__name', 'club__league')

ManyToMany поля больше трудный. Они могут потребовать агрегации или extra и select вызовы в окне QueryManager.


попробуйте этот код

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))

на самом деле есть утилита, которая позволяет экспортировать данные csv из запросов Django со всеми его функциями из цепочек в поля поиска: django-queryset-csv.

использование exapmle:

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 дополнительные примеры использования. Надеюсь, вы найдете это полезным.