follow relationships on ForeignKeyWidget

This commit is contained in:
Manel Clos 2018-06-28 11:12:33 +02:00
parent 420651ffb0
commit 622a625387
4 changed files with 89 additions and 2 deletions

View File

@ -7,6 +7,7 @@ from django.utils import datetime_safe, timezone, six
from django.utils.encoding import smart_text
from django.utils.dateparse import parse_duration
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
try:
from django.utils.encoding import force_text
@ -343,7 +344,19 @@ class ForeignKeyWidget(Widget):
def render(self, value, obj=None):
if value is None:
return ""
return getattr(value, self.field)
attrs = self.field.split('__')
for attr in attrs:
try:
value = getattr(value, attr, None)
except (ValueError, ObjectDoesNotExist):
# needs to have a primary key value before a many-to-many
# relationship can be used.
return None
if value is None:
return None
return value
class ManyToManyWidget(Widget):

View File

@ -0,0 +1,34 @@
# Generated by Django 2.0.2 on 2018-06-28 04:11
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('core', '0006_auto_20171130_0147'),
]
operations = [
migrations.CreateModel(
name='Person',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
),
migrations.CreateModel(
name='Role',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('user', models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.AddField(
model_name='person',
name='role',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Role'),
),
]

View File

@ -68,6 +68,14 @@ class Entry(models.Model):
user = models.ForeignKey('auth.User', on_delete=models.CASCADE)
class Role(models.Model):
user = models.OneToOneField('auth.User', on_delete=models.CASCADE, null=True)
class Person(models.Model):
role = models.ForeignKey(Role, on_delete=models.CASCADE)
class WithDefault(models.Model):
name = models.CharField('Default', max_length=75, blank=True,
default='foo_bar')

View File

@ -21,7 +21,7 @@ from import_export.resources import Diff
from ..models import (
Author, Book, Category, Entry, Profile, WithDefault, WithDynamicDefault,
WithFloatField,
WithFloatField, Person, Role
)
try:
@ -935,6 +935,38 @@ if 'postgresql' in settings.DATABASES['default']['ENGINE']:
self.assertListEqual(book_with_chapters.chapters, chapters)
class ForeignKeyWidgetFollowRelationship(TestCase):
def setUp(self):
self.user = User.objects.create(username='foo')
self.role = Role.objects.create(user=self.user)
self.person = Person.objects.create(role=self.role)
def test_export(self):
class MyPersonResource(resources.ModelResource):
role = fields.Field(
column_name='role',
attribute='role',
widget=widgets.ForeignKeyWidget(Role, field='user__username')
)
class Meta:
model = Person
fields = ['id', 'role']
resource = MyPersonResource()
dataset = resource.export(Person.objects.all())
self.assertEqual(len(dataset), 1)
self.assertEqual(dataset[0][0], 'foo')
self.role.user = None
self.role.save()
resource = MyPersonResource()
dataset = resource.export(Person.objects.all())
self.assertEqual(len(dataset), 1)
self.assertEqual(dataset[0][0], None)
class ManyRelatedManagerDiffTest(TestCase):
fixtures = ["category", "book"]