question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Manytomany widget- M2M fields appear blank in export via Admin export

See original GitHub issue

I have the following models and M2M relationships:

class Market(models.Model):
    marketname = models.CharField(max_length=500)
    market_id = models.CharField(max_length=100, blank=True)

    def __str__(self):
        return self.marketname

class TeamMember(models.Model):
    firstname = models.CharField(max_length=100, default= "First Name")
    lastname = models.CharField(max_length=100, default= "Last Name")
    email = models.EmailField(max_length=254)

    def __str__(self):
        return self.email

class EmailReport(models.Model):
    name = models.CharField(max_length=1000)
    recipients = models.ManyToManyField('team.TeamMember', related_name="teamrecipients")
    frequency = models.CharField(max_length=1000, blank= True)
    markets = models.ManyToManyField('opportunities.Market', blank=True)
    def __str__(self):
        return self.name

The following is my admin.py for the EmailReport registration.

class EmailReportResource(resources.ModelResource):
    recipients = fields.Field(widget=ManyToManyWidget(TeamMember, field="email"))
    markets = fields.Field(widget=ManyToManyWidget(Market, field='marketname'))
    class Meta:
        model = EmailReport
        fields = ['id', 'name', 'recipients', 'markets']

class EmailReportAdmin(ImportExportModelAdmin):
    resource_class = EmailReportResource

admin.site.register(EmailReport, EmailReportAdmin)

I am able to export- and all char fields export normally- however, my M2M fields all appear blank.

Can anyone please point out my mistake?

Thank you so much!

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
jackkinsellacommented, Mar 10, 2021

Same issue.

Update: I solved with the following code (I believe by adding attribute to Field)

class EventResource(models.ModelResource):
    tags = fields.Field(attribute="tags", widget=widgets.ManyToManyWidget(Tag, field='name'))
   ...
   
   class Meta:
             fields = (... 'tags__name')

1reaction
n8thanaelcommented, Jun 7, 2022

I hope this helps someone dealing with the issue of M2M Fields appearing blank via Admin. I found that when I passed ‘field’ kwarg in the in the ManyToManyWidget(field=‘code’) it would work properly on the export portion (render() method) - but ‘field’ was defaulting to None when on the import. IDK why that was, but this is how I solved it. I created a customM2M widget class from ManyToManyWidget that first helped me diagnose the problem, and then made a new kwarg called ‘m2mField’ that I could pass ‘code’ in a second time - that would both make the export and import function correctly.

models.py

class TaxonomyTerm(StatusModel):
    code = models.CharField(
        primary_key=True,
        )
        
class AcademicPage(StatusModel):
    title = models.CharField()
    faculty_department = models.ManyToManyField(
        TaxonomyTerm,
        )

admin.py

from .custom_widgets import CustomM2M

class academicPageResource(resources.ModelResource):
    faculty_department = fields.Field(
        column_name='faculty_department',
        attribute='faculty_department',
        # Custom M2M was required here, because for some reason field='code'
        # wasn't being passed through to the normal import 'clean()' method
        # within the ManyToManyWidget() class - it did work on export or
        # 'render()' but didn't work at all on 'clean()' - it would revert to
        # "pk" which is normally correct, but my model specifies the primary
        # key as 'code'
        widget=CustomM2M(model=TaxonomyTerm, field='code', m2mField='code')
    )
    class Meta:
        fields = ('id','title')
        exclude = ('body_a','body_b','slug')
        model = AcademicPage

class Admin_academicpages(ImportExportModelAdmin):
    resource_class = academicPageResource

custom_widgets.py

from import_export.widgets import ManyToManyWidget

# this custom widget was built because the kwarg 'field' wasn't carrying in
# the 'code' needed to properly build out the model.object.filter(), it would
# default to 'pk' which wasn't the default primary key for my objects
class CustomM2M(ManyToManyWidget):
    def __init__(self, model, separator=None, field=None, *args, **kwargs):
        print(args)
        print(kwargs)
        if separator is None:
            separator = ','
        # IDKW, but field always comes in as None, even when set in admin.py
        if field is None:
            field = 'pk'
        self.model = model
        self.separator = separator
        self.field = field
        # added a new field that can carry the proper column name 'code' over
        self.m2mField = kwargs.get('m2mField', None)
        super(CustomM2M, self).__init__(model)

    # clean is the 'import' method that prepares the data received in a way
    # that will return well-formed django db - model.objects via filter()
    def clean(self, value, row=None, *args, **kwargs):
        if not value:
            return self.model.objects.none()
        if isinstance(value, (float, int)):
            ids = [int(value)]
        else:
            ids = value.split(self.separator)
            ids = filter(None, [i.strip() for i in ids])


        if self.m2mField is not None:
            id_field = '%s__in' % self.m2mField
            return self.model.objects.filter(**{id_field:ids})
        else 
            return self.model.objects.filter(**{
                '%s__in' % self.field: ids
Read more comments on GitHub >

github_iconTop Results From Across the Web

Error import m2m widget django import-export - Stack Overflow
The issue is skip_unchanged = True . This may seem unintuitive, but it should read skip_unchanged = False . To understand the reason...
Read more >
Django Import Export Tricks & Tips - Dev Genius
Django Import Export Tricks & Tips · Look Up in Foreignkey and ManyToMany fields · Custom Dropdown Widgets · Skip Rows (Avoid Duplicate...
Read more >
django-import-export Documentation - Read the Docs
To affect which model fields will be included in an import-export resource ... The ForeignKeyWidget also supports using Django's natural key ...
Read more >
django-import-export - Bountysource
Django application and library for importing and exporting data with admin integration. Become a Bounty Hunter You're a Bounty Hunter. View Bounties ...
Read more >
django-import-export 数据导入导出 | We all are data. - pointborn
T affect which model fields will be included in an import-export resource, ... appear in the import Result object, and if using the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found