Django-import-export: Best way to avoid RelatedObjectDoesNotExist on row_result.object_repr attribute initialisation

Created on 19 Apr 2016  路  6Comments  路  Source: django-import-export/django-import-export

Hello, I have 2 models:

class Candidate(models.Model):
    first_name = models.CharField(_("First name"), max_length=255)

class Test(models.Model):
    candidate = models.OneToOneField(Candidate)

    def __str__(self):
        return self.candidate.first_name

In Test model candidate is required field and I want to show first_name in Django admin (in selects, for example)

When I try to import data for Test model, I get RelatedObjectDoesNotExist. This line of code
https://github.com/django-import-export/django-import-export/blob/master/import_export/resources.py#L414 throw an Exception for newly created instances, before I can skip invalid rows.

Do you have any best practices to avoid this kind of error on import? I'm not sure that I really like an idea always check FK existence in __str__ method to fix this behaviour, but can't think of something better.
Thanks.

stale

Most helpful comment

Regarding the importing of RelatedObjectDoesNotExist, it's actually a property of Django's ReverseSingleRelatedObjectDescriptor which, if you look at the code, raises actually the DoesNotExist of the related field, which has for base class ObjectDoesNotExist

class ReverseSingleRelatedObjectDescriptor(object):

    @cached_property
    def RelatedObjectDoesNotExist(self):
        return type(
            str('RelatedObjectDoesNotExist'),
            (self.field.rel.to.DoesNotExist, AttributeError),
            {}
        )

To complete @JarnoRFB comment above, I think the try-except should be limited to this exception in the __str__ (or __unicode__ in python 2) like below, and return something safe and recognisable in case of failure:

from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.db import models

class MyModel(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)

    def __unicode__(self):
        try:
            return "{0}".format(self.user)
        except ObjectDoesNotExist:
            return "[MyModel instance]"

All 6 comments

The same problem confused me for the entire morning, because I thought the import was broken. In the end I just did something like:

def __str__(self):
    try:
        return '{} -- {}'.format(self.myname, self.realatedmodel.yourname)
    except:
        return '{}'.format(self.myname)

which I believe is conform with the Python EAFP principle. Though I would like to just except the RelatedObjectDoesNotExist exception, but I couldn't correctly import it.

Probably it could be an option to create all the objects on the dry-run and then call the save method only in process_import. But I have just started to use this library, which I think is great by the way, so I cannot tell how to achieve something like this.

Regarding the importing of RelatedObjectDoesNotExist, it's actually a property of Django's ReverseSingleRelatedObjectDescriptor which, if you look at the code, raises actually the DoesNotExist of the related field, which has for base class ObjectDoesNotExist

class ReverseSingleRelatedObjectDescriptor(object):

    @cached_property
    def RelatedObjectDoesNotExist(self):
        return type(
            str('RelatedObjectDoesNotExist'),
            (self.field.rel.to.DoesNotExist, AttributeError),
            {}
        )

To complete @JarnoRFB comment above, I think the try-except should be limited to this exception in the __str__ (or __unicode__ in python 2) like below, and return something safe and recognisable in case of failure:

from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.db import models

class MyModel(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)

    def __unicode__(self):
        try:
            return "{0}".format(self.user)
        except ObjectDoesNotExist:
            return "[MyModel instance]"

This should be fixed in master now.

Fixed in 0.6.0 with #505

Looks like I'm getting similar issue again with 1.0.1. Will add details later, maybe that's some error on my end.

Update: The error was the assumption that fields with __ in attribute will be readonly automatically. Was this behaviour changed during development?

I guess this issue can be closed now.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Rubyj picture Rubyj  路  4Comments

leotop picture leotop  路  6Comments

skolomiiets picture skolomiiets  路  4Comments

gone picture gone  路  5Comments

aidanlister picture aidanlister  路  5Comments