使用具有反向外键关系的模型导出 xlsx 文件,并将该反向外键关系作为单独的列
Export xlsx file with model having reverse foreign key relation and make that reverse foreign key relation as separate column
我正在使用 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', max_length=45, blank=True, null=True)
phone = models.CharField(
db_column='PHONE', max_length=45, blank=True, null=True)
email = models.CharField(
db_column='EMAIL', max_length=45, blank=True, null=True)
gender = models.CharField(
db_column='GENDER', max_length=45, blank=True, 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, on_delete=models.CASCADE,
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, blank=True, null=True)
correct_answer = models.IntegerField(
db_column='CORRECT_ANSWER', blank=True, null=True)
load_id = models.IntegerField(db_column='LOAD_ID', blank=True, null=True)
class SurveyQuestions(models.Model):
"""
Model for surveys questions
"""
survey = models.ForeignKey(Surveys, on_delete=models.CASCADE,
db_column='SURVEY_ID', 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', max_length=255, blank=True, null=True)
response_type = models.CharField(
db_column='RESPONSE_TYPE', max_length=255, blank=True, 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 模型,但最后三列 headers 表示来自 SurveyQuestions 模型的“question”字段,值来自 Responses 模型的“response”字段。
到目前为止,我可以实现以下格式:
first_name, last_name, phone, email, given
abc, xyz, 1234566780, abc@gmail.com, {question1: response1, question2: response2, question3: response3}
给定的字段是 json 的 question-response 作为 key-value 对。
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()
中,您将可以访问数据集和查询集,因此希望您可以操作此数据以正确填充 'response' 列。
我正在使用 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', max_length=45, blank=True, null=True)
phone = models.CharField(
db_column='PHONE', max_length=45, blank=True, null=True)
email = models.CharField(
db_column='EMAIL', max_length=45, blank=True, null=True)
gender = models.CharField(
db_column='GENDER', max_length=45, blank=True, 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, on_delete=models.CASCADE,
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, blank=True, null=True)
correct_answer = models.IntegerField(
db_column='CORRECT_ANSWER', blank=True, null=True)
load_id = models.IntegerField(db_column='LOAD_ID', blank=True, null=True)
class SurveyQuestions(models.Model):
"""
Model for surveys questions
"""
survey = models.ForeignKey(Surveys, on_delete=models.CASCADE,
db_column='SURVEY_ID', 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', max_length=255, blank=True, null=True)
response_type = models.CharField(
db_column='RESPONSE_TYPE', max_length=255, blank=True, 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 模型,但最后三列 headers 表示来自 SurveyQuestions 模型的“question”字段,值来自 Responses 模型的“response”字段。
到目前为止,我可以实现以下格式:
first_name, last_name, phone, email, given
abc, xyz, 1234566780, abc@gmail.com, {question1: response1, question2: response2, question3: response3}
给定的字段是 json 的 question-response 作为 key-value 对。
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()
中,您将可以访问数据集和查询集,因此希望您可以操作此数据以正确填充 'response' 列。