Studio Rooster Studio Rooster - 1 month ago 6
Python Question

How to export a Django model including ForeignKey model relationships into a combined text file

I have a Django model that has several ForeignKey model relationships that I need to combine into single records.

If you look at my

plaque
model below, you'll notice I have a ForeignKey relationship to a
veteran
model. I created a veteran model without truly thinking it through and now need to add the veteran fields to my plaque model, but need to export all the data first, rebuild my plaque model, then re-import the data.

I've have django-import-export installed and it works great for single models. I exported my plaque data and in the veteran field it just adds the id number of the related veteran. What I'd like to do, if possible, is actually export my plaque model and instead of the related veterans id number, the actual data from the veteran models(first_name, last_name etc). I am also using PostgreSQL if that helps. Any ideas? Thank you.

class Plaque(models.Model):
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='plaques', default=1)
group = models.ForeignKey(Group, blank=True, null=True, verbose_name='Group Name')
veteran = models.ForeignKey(Veteran, blank=True, null=True)
...


UPDATE - Here is my entire resource model solution. This will export a file with the string values of all my ForeignKey model fields.

from import_export import resources, fields
from import_export.widgets import ForeignKeyWidget
from import_export.admin import ImportExportModelAdmin
from .models import Plaque, Group, Veteran, Service, Branch, War, Rank
from django.contrib import admin


class PlaqueResource(resources.ModelResource):
vet_first = fields.Field(column_name='Veteran First', attribute='veteran', widget=ForeignKeyWidget(Veteran, field='first_name'))
vet_middle = fields.Field(column_name='Veteran Middle', attribute='veteran', widget=ForeignKeyWidget(Veteran, field='middle_name'))
vet_last = fields.Field(column_name='Veteran Last', attribute='veteran', widget=ForeignKeyWidget(Veteran, field='last_name'))
vet_display = fields.Field(column_name='Veteran Display Name', attribute='veteran', widget=ForeignKeyWidget(Veteran, field='display_name'))
vet_nick = fields.Field(column_name='Veteran Nickname', attribute='veteran', widget=ForeignKeyWidget(Veteran, field='nickname'))
vet_bio = fields.Field(column_name='Veteran Biography', attribute='veteran', widget=ForeignKeyWidget(Veteran, field='biography'))
vet_branch = fields.Field(column_name='Veteran Branch - service model', attribute='service', widget=ForeignKeyWidget(Service, field='branch'))
vet_rank = fields.Field(column_name='Veteran Rank - service model', attribute='service', widget=ForeignKeyWidget(Service, field='rank'))
vet_war = fields.Field(column_name='Veteran War - service model', attribute='service', widget=ForeignKeyWidget(Service, field='war'))
vet_branch2 = fields.Field(column_name='Veteran Branch - branch model', attribute='service', widget=ForeignKeyWidget(Branch, field='branch'))
vet_rank2 = fields.Field(column_name='Veteran Rank - rank model', attribute='service', widget=ForeignKeyWidget(Rank, field='rank'))
vet_war2 = fields.Field(column_name='Veteran War - war model', attribute='service', widget=ForeignKeyWidget(War, field='war'))
group_name = fields.Field(column_name='Group Name', attribute='group', widget=ForeignKeyWidget(Group, field='group_name'))
group_type = fields.Field(column_name='Group Type', attribute='group', widget=ForeignKeyWidget(Group, field='group_type'))

class Meta:
model = Plaque

Answer Source

This should work, (from the docs)

# Or however your resources look
class PlaqueResource(resources.ModelResource):

    class Meta:
        model = Plaque
        fields = (<other_fields>, 'veteran__first_name', 'veteran__last_name',)