微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用具有反向外键关系的模型导出xlsx文件,并将该反向外键关系作为单独的列

如何解决使用具有反向外键关系的模型导出xlsx文件,并将该反向外键关系作为单独的列

我正在使用django import_export软件包将数据导出到xlsx文件中。

以所需的格式将数据导出到excel时出现问题。

models.py

class Fans(models.Model):
    """
        Model for survey answering people
    """
    fan_id = models.AutoField(db_column='FAN_ID',primary_key=True)
    first_name = models.CharField(
        db_column='FirsT_NAME',max_length=45,blank=True,null=True)
    last_name = models.CharField(
        db_column='LAST_NAME',null=True)
    phone = models.CharField(
        db_column='PHONE',null=True)
    email = models.CharField(
        db_column='EMAIL',null=True)
    gender = models.CharField(
        db_column='GENDER',null=True)

class Responses(models.Model):
    """
        Model for responses given by fans
    """
    survey = models.ForeignKey(
        Surveys,on_delete=models.CASCADE,db_column='SURVEY_ID',related_query_name="part")
    fan = models.ForeignKey(Fans,db_column='FAN_ID',related_query_name="given",related_name="given")
    survey_question = models.ForeignKey(
        SurveyQuestions,on_delete=models.DO_nothing,db_column='SURVEY_QUESTION_ID',related_query_name="response")
    response = models.CharField(
        db_column='RESPONSE',max_length=255,null=True)
    correct_answer = models.IntegerField(
        db_column='CORRECT_ANSWER',null=True)
    load_id = models.IntegerField(db_column='LOAD_ID',null=True)

class SurveyQuestions(models.Model):
    """
        Model for surveys questions
    """
    survey = models.ForeignKey(Surveys,related_query_name="question")
    survey_question_id = models.AutoField(
        db_column='SURVEY_QUESTION_ID',primary_key=True)
    survey_question_name = models.CharField(
        db_column='SURVEY_QUESTION_NAME',max_length=255)
    question = models.CharField(
        db_column='QUESTION',null=True)
    response_type = models.CharField(
        db_column='RESPONSE_TYPE',null=True)
    load_date = models.DateField(db_column='LOAD_DATE',auto_Now_add=True)

我想以以下格式导出记录了响应的粉丝数据:

first_name,last_name,phone,email,question1,question2,question3
abc,xyz,1234566780,abc@gmail.com,response1,response2,response3

这里,前四个字段直接来自Fans模型,但是后三个列标题表示SurveyQuestions模型的“ question”字段,值来自Responses模型的“ response”字段。

到目前为止,我能够实现以下格式:

first_name,given
abc,{question1: response1,question2: response2,question3: response3}

给定字段是问题响应的json作为键值对。

admin.py

class FanResource(resources.ModelResource):

    """
        Resource for exporting to excel
    """

    given = fields.Field()

    class Meta:
        model = Fans
        fields = ("first_name","last_name","email","phone","given")

    def dehydrate_given(self,instance):
        res = {}
        for x in instance.given.values('response','survey_question__question'):
            res[x['survey_question__question']] = x['response']
        return json.dumps(res)

任何帮助将不胜感激。预先感谢!

14/10/20更新

使用下面的答案,我能够实现所需的格式。代码如下:

def after_export(self,queryset,data,*args,**kwargs):
        survey_questions = {x["survey_question_id"]: x["question"] for x in SurveyQuestions.objects.filter(
            survey=self.survey).values('survey_question_id','question')}
        for k,v in survey_questions.items():
            res = []
            for x in queryset:
                try:
                    res.append(x.given.get(survey_question=k).response)
                except ObjectDoesNotExist:
                    res.append(None)
            data.append_col(res,header=v)

现在,问题在于,它要花很长时间才能访问每个条目的数据库。还有一个问题是顺序不正确(即响应与对应的粉丝不在同一行)。

解决方法

我认为实现此目标的方法是覆盖after_export(),并处理导出的数据集。例如:

    def after_export(self,queryset,data,*args,**kwargs):
        response1 = [i for i in range(data.height)]
        data.append_col(response1,header="response1")
        response2 = [i for i in range(data.height)]
        data.append_col(response2,header="response2")

这会将新列追加到导出的末尾。在after_export()中,您将可以访问数据集和查询集,因此希望您可以操纵这些数据以正确填充“响应”列。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。