【问题标题】:Django-import-export accessing fields in file not used by the ModelResourceDjango-import-export 访问 ModelResource 未使用的文件中的字段
【发布时间】:2019-01-09 11:23:22
【问题描述】:

原来的问题贴在这里:https://github.com/django-import-export/django-import-export/issues/886

大家好,

我有一个包含以下列的 xslx 文档:

类别 |场地 |活动 |问题 |答案 |客户 |行动

Category、Venue、Event 和 Client 是 ForeignKeys。如果它们不存在,则应创建它们,因此我创建了自定义 ForeignKeyWidgets:

class ForeignKeyWidgetWithCreation(ForeignKeyWidget):
    def __init__(
            self,
            model,
            field='pk',
            create=False,
            *args, **kwargs):
        self.model = model
        self.field = field
        self.create = create
        # super(ForeignKeyWidgetWithCreation, self).__init__(*args, **kwargs)

    def clean(self, value, row=None, *args, **kwargs):
        val = super(ForeignKeyWidgetWithCreation, self).clean(value)
        if self.create:
            instance, new = self.model.objects.get_or_create(**{
                self.field: val
            })
            val = getattr(instance, self.field)
        return self.model.objects.get(**{self.field: val}) if val else None


# Event Widget
class EventWidget(ForeignKeyWidget):
    def __init__(
            self,
            model,
            field='pk',
            create=False,
            *args, **kwargs):
        self.model = model
        self.field = field
        self.create = create
        # super(ForeignKeyWidgetWithCreation, self).__init__(*args, **kwargs)

    def clean(self, value, row=None, *args, **kwargs):
        val = super(ForeignKeyWidgetWithCreation, self).clean(value)
        if self.create:
            instance, new = self.model.objects.get_or_create(**{
                self.field: val
            })
            val = getattr(instance, self.field)
        return self.model.objects.get(**{self.field: val}) if val else None


# CLIENT WIDGET
class ClientWidget(ForeignKeyWidget):
    def __init__(self, model, field='client', *args, **kwargs):
        self.model = Client
        self.field = field

    def clean(self, value, row=None, *args, **kwargs):
        val = super(ClientWidget, self).clean(value)
        if val:
            client = Client.objects.get_or_create(name=val)
            return client
            # return self.get_queryset(value, row, *args, **kwargs).get(**{self.field: val})
        else:
            return None


# VENUE WIDGET
class VenueWidget(ForeignKeyWidget):
    def __init__(self, model, field='pk', *args, **kwargs):
        self.model = model
        self.field = field
        self.other_widget = ClientWidget(model=Client)

    def clean(self, value, row=None, *args, **kwargs):
        client = self.other_widget.clean(row['client'], row)
        print(client)
        return self.model.objects.get_or_create(venue=value, client=client)

我的模型资源如下:

class QuestionResource(resources.ModelResource):
    category = fields.Field(
        column_name='category',
        attribute='category',
        widget=ForeignKeyWidgetWithCreation(Category, 'category')
    )
    venue = fields.Field(
        column_name='venue',
        attribute='venue',
        widget=VenueWidget(Venue, 'venue')
    )
    event = fields.Field(
        column_name='event',
        attribute='event',
        widget=ForeignKeyWidgetWithCreation(Event, 'event')
    )
    client = fields.Field(
        column_name='client',
        attribute='client',
        widget=ClientWidget(Client, 'name')
    )

    class Meta:
        model = Question
        fields = ['id', 'question', 'venue', 'category', 'answer', 'event', 'client']

我的模型没有客户端字段关系,但我想根据它是否存在来创建一个新的客户端。

目前,当我上传 xlsx 文件时,我收到以下错误:

django.core.exceptions.FieldError: Cannot resolve keyword 'client' into field. Choices are: created, id, modified, name, profile, question, update, venue

我明白为什么会这样,但我不知道如何访问另一个列值并使用它来为我的其他外键创建关系。

创建模型 Venue 和 Event 时,它们需要 Client 父模型。由于我的问题没有这种关系,我需要创建它,以便可以创建我的其他模型(活动和场地)。

提前致谢!

【问题讨论】:

    标签: python django django-2.0 django-import-export


    【解决方案1】:

    我终于解决了这一切。这是我的 admin.py。希望对你有帮助!

    from import_export.admin import ImportExportModelAdmin
    from django.contrib import admin
    from .models import Question, Category
    from events.models import Event
    from import_export import resources, fields
    from import_export.widgets import ForeignKeyWidget, DateTimeWidget
    from django_summernote.admin import SummernoteModelAdmin
    from clients.models import Client
    from venues.models import Venue
    
    
    # EVENT WIDGET
    class EventWidget(ForeignKeyWidget):
        def __init__(
                self,
                model,
                field='pk',
                create=False,
                *args, **kwargs):
            self.model = model
            self.field = field
            self.create = create
    
        def clean(self, value, row=None, *args, **kwargs):
            venue_row_value = row["venue"]
            venue = Venue.objects.filter(venue__iexact=venue_row_value).first()
            obj, created = self.model.objects.get_or_create(event=value, venue=venue)
            return obj
    
    # CLIENT WIDGET
    class ClientWidget(ForeignKeyWidget):
        def __init__(
                self,
                model,
                field='pk',
                create=False,
                *args, **kwargs):
            self.model = model
            self.field = field
            self.create = create
    
        def clean(self, value, row=None, *args, **kwargs):
            obj, created = self.model.objects.get_or_create(name=value)
            return obj
    
    
    # VENUE WIDGET
    class VenueWidget(ForeignKeyWidget):
        def clean(self, value, row=None, *args, **kwargs):
            client = Client.objects.get(name__iexact=row["client"])
            obj, created = self.model.objects.get_or_create(venue=value, client=client)
            return obj
    
    
    class CategoryWidget(ForeignKeyWidget):
        def clean(self, value, row=None, *args, **kwargs):
            obj, created = self.model.objects.get_or_create(category=value)
            return obj
    
    
    class QuestionResource(resources.ModelResource):
        client = fields.Field(
            column_name='client',
            attribute='client',
            widget=ClientWidget(Client, 'name')
        )
        category = fields.Field(
            column_name='category',
            attribute='category',
            widget=CategoryWidget(Category, 'category')
        )
        venue = fields.Field(
            column_name='venue',
            attribute='venue',
            widget=VenueWidget(Venue, 'venue')
        )
        event = fields.Field(
            column_name='event',
            attribute='event',
            widget=EventWidget(Event, 'event')
        )
    
        class Meta:
            model = Question
            fields = ['id', 'client', 'question', 'venue', 'category', 'answer', 'event',]
    
    
    @admin.register(Question)
    class QuestionAdmin(ImportExportModelAdmin, SummernoteModelAdmin):
        exclude = ('verified_by',)
        resource_class = QuestionResource
        summernote_fields = ('answer', 'info')
        # Displays the columns in the admin page overview of questions
        list_display = ('question', 'event', 'category', 'verified', 'verified_by',)
        # Immediately edit the model by clicking on the question, category or verified
        list_display_links = ('question', 'event', 'category', 'verified')
    
        # filtering in the adminpage:
        list_filter = ('verified', 'event', 'category',)
    
        def save_model(self, request, obj, form, change):
            if obj.verified == True:
                obj.verified_by = request.user
            else:
                obj.verified_by = None
            super().save_model(request, obj, form, change)
    
    
    admin.site.register(Category)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-11
      • 1970-01-01
      • 2021-03-07
      • 2013-11-13
      • 2023-02-08
      • 2015-05-08
      • 1970-01-01
      • 2021-08-11
      相关资源
      最近更新 更多