GVKun编程网logo

django-import-export:实例数据在保存后(种族条件)未更新(django保存数据到数据库)

15

针对django-import-export:实例数据在保存后和种族条件未更新这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Djangoimport/export实现数据库导入导出、dja

针对django-import-export:实例数据在保存后种族条件未更新这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Django import / export实现数据库导入导出、django import和django-import-export、Django 调用报错 " ImportError: Couldn''t import Django. "、django-import-export 显示model verbose_name等相关知识,希望可以帮助到你。

本文目录一览:

django-import-export:实例数据在保存后(种族条件)未更新(django保存数据到数据库)

django-import-export:实例数据在保存后(种族条件)未更新(django保存数据到数据库)

如何解决django-import-export:实例数据在保存后(种族条件)未更新?

我有一个允许通过django-import-export导入的模型。

在导入Event实例后,我需要创建相关对象,因此我将使用after_save_instance来启动芹菜任务,该任务通过ID引用对象。但是在这些任务中,当我使用从Resource类传递的ID从数据库中检索对象时,我会得到旧数据。

例如,导入的数据会更改现有date对象上的Event值,并且在after_save_instance期间会更新数据,但是一旦celery任务检索到数据,它就会有所不同。 / p>

这是精简的资源类;

class EventImportResource(resources.ModelResource):
    """ Admin importer for Events """
    date = fields.Field(
        attribute=''date'',column_name=''date'',widget=LocalisedDateWidget(
            format=get_format(''UK_DATE_INPUT_FORMATS'')
        )
    )

    class Meta:
        model = Event

        fields = [
            ''id'',''date'',''name'',''city'',''state'',''country'',''url''
        ]

    def after_save_instance(self,instance,using_transactions,dry_run):
        """
        Override to add additional logic. Does nothing by default.
        """
        if not dry_run:
            transaction.on_commit(lambda: create_categories.delay(instance.id))


            # debugging at this point shows the new value
            # >>> instance.date
            # webapp_1           | datetime.date(2020,10,25)

在celery任务中,我需要从数据库中获取对象并执行其他一些对象创建等操作。这时,实例上的属性与after_save_instance中的实例不同。

@celery_app.task
def create_categories(event_id):
    """
    Create Category objects for an event

    :param event_id: Event ID
    :return:
    """
    time.sleep(30)  # Doesn''t seem to help
    categories = []
    instance = Event.objects.get(id=event_id)
    instance.refresh_from_db()  # Tried this to resolve the issue,but didn''t help

    # debugging at this point shows the old value
    # >>> instance.date
    # webapp_1           | datetime.datetime(2020,24,23,tzinfo=<UTC>)

在保存实例(docs)之后将调用resource方法,因此这只能是由于在提交事务之前拾取了celery任务引起的竞争条件。尽管有尝试等待on_commit()sleep的芹菜来接班的情况。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

Django import / export实现数据库导入导出

Django import / export实现数据库导入导出

使用django-import-export库,导入导出数据,支持csv、xls、json、html等格式

官网:http://django-import-export.readthedocs.io/en/latest/installation.html

1、安装django-import-export

pip install django-import-export

2、配置settings.py

INSTALLED_APPS = (
    ''django.contrib.admin'',
    ''django.contrib.auth'',
    ''django.contrib.contenttypes'',
    ''django.contrib.sessions'',
    ''django.contrib.messages'',
    ''django.contrib.staticfiles'',
    ''customer'',
    ''publisher'',
    ''import_export'',
)

执行命令: python manage.py collectstatic

3、models.py 建立model

class Author(models.Model):
    name = models.CharField(max_length=100)

    def __unicode__(self):
        return self.name


class Category(models.Model):
    name = models.CharField(max_length=100)

    def __unicode__(self):
        return self.name


class Book(models.Model):
    name = models.CharField(''Book name'', max_length=100)
    author = models.ForeignKey(Author, blank=True, null=True)
    author_email = models.EmailField(''Author email'', max_length=75, blank=True)
    imported = models.BooleanField(default=False)
    published = models.DateField(''Published'', blank=True, null=True)
    price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
    categories = models.ManyToManyField(Category, blank=True)

    def __unicode__(self):
        return self.name

4、在admin.py 创建Resource、对应的Admin

from import_export import resources
from core.models import Book
from import_export.admin import ImportExportModelAdmin


class BookResource(resources.ModelResource):

    class Meta:
        model = Book
        export_order = (''id'', ''name'', ''author'', ''author_email'', ''imported'', ''click'', ''published'', ''price'', ''categories'')

@admin.register(Book)
class BookAdmin(ImportExportModelAdmin):
    list_display = (''name'', ''author'', ''author_email'', ''imported'', ''published'', ''price'', ''categories'')
    search_fields = (''name'', ''author'',''published'')
    date_hierarchy = ''date''   
    resource_class = BookResource

export_order:设置导出字段的顺序

5、Django界面实现导入导出

自测发现,导出xlsx格式不支持,其他正常。

 

 

 

 

 

 

 

 

django import和django-import-export

django import和django-import-export

我认为此问题可能是由以下原因引起的:

  1. csv中的标头名称与模型属性名称不匹配(例如,“姓氏”应为“姓氏”)。

  2. 库或应用程序代码中一些未发现的错误。

我还注意到您的csv行包含4个字段,但您声明了5个标头(没有为“ id”提供值)。

除此之外,我看不到任何问题。 Python 3.8应该没问题。

如果找到问题的根源,请进行更新。

Django 调用报错

Django 调用报错 " ImportError: Couldn''t import Django. "

系统炸了导致不得已重装

安装 Django后 利用ORM 创建表的时候报错 

1 Traceback (most recent call last):
2   File "manage.py", line 17, in <module>
3     "Couldn''t import Django. Are you sure it''s installed and "
4 ImportError: Couldn''t import Django. Are you sure it''s installed and available on your PYTHONPATH environment variable? Did you forget to activate a virtual environment?
5 
6 F:\python_django>python manage.py makemigrations

 

提示不能导入。我是用的pycharm导入方式。而且在pycharm中也可以看到

 

有点不科学。那就用普通的方式再来一次试试。

 

这次的报错多少科学点了。虽然我不是很懂这个报错是什么原因。但是提示的是语法错误,找到错误位置看下

1    from django.contrib.admin.options import IncorrectLookupParameters
2   File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\contrib\admin\options.py", line 12, in <module>
3     from django.contrib.admin import helpers, widgets
4   File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\contrib\admin\widgets.py", line 152
5     ''%s=%s'' % (k, v) for k, v in params.items(),
6     ^
7 SyntaxError: Generator expression must be parenthesized

 

程序开发的源码,看起来也没有什么错误。但是我就是觉得那个逗号有点怪。很没有必要的感觉。反正走到这里暂时也没办法。去掉试下?

虽然提示不要改,但是我觉得这个逗号确实没意义。去掉反正也没有什么影响。

 

我去?你在逗我。。。

 

事后查阅了很多的资料以及其他人的分享。关于貌似是因为mysql数据库的版本问题导致。在Python3.6以上的版本会出现这种问题,大概吧。关于这个现象我只找到了一位和我有相同经历的博文。他的解决方法也是一样去掉了逗号,

 

总结:这是一个神奇的逗号。

django-import-export 显示model verbose_name

django-import-export 显示model verbose_name

安装并配置django-import-export

pip install django-import-export
pip install django-simpleui

 

配置settings.py

# settings.py
INSTALLED_APPS = (
    ''simpleui'',
    ''import_export'',
)

建立model

from django.db import models


# Create your models here.
# 商品表
class commodity(models.Model):
    name = models.CharField(max_length=225, verbose_name="商品名称", blank=True, default="")
    desc = models.TextField(verbose_name="商品描述", blank=True)

    class Meta:
        verbose_name_plural = "商品表"

    def __str__(self):
        return self.name

生成数据库迁移

python manage.py makemigrations
python manage.py migrate

 

配置 admin.py

from django.contrib import admin
from app import models
from import_export import resources
from import_export.admin import ImportExportModelAdmin
from django.apps import apps

admin.site.site_header = "XXX后台管理"
admin.site.site_title = "XXX后台"


# Register your models here.
class commodityResource(resources.ModelResource):

    def __init__(self):
        super(commodityResource, self).__init__()

        field_list = models.commodity._meta.fields
        self.vname_dict = {}
        for i in field_list:
            self.vname_dict[i.name] = i.verbose_name

    # 默认导入导出field的column_name为字段的名称,这里修改为字段的verbose_name
    def get_export_fields(self):
        fields = self.get_fields()
        for field in fields:
            field_name = self.get_field_name(field)
            # 如果我们设置过verbose_name,则将column_name替换为verbose_name。否则维持原有的字段名
            if field_name in self.vname_dict.keys():
                field.column_name = self.vname_dict[field_name]
        return fields

    def after_import(self, dataset, result, using_transactions, dry_run, **kwargs):
        print("after_import")

    def after_import_instance(self, instance, new, **kwargs):
        print("after_import_instance")

    class Meta:
        model = models.commodity
        skip_unchanged = True
        report_skipped = True
        fields = ("id", "name", "desc")


@admin.register(models.commodity)
class AppTypeAdmin(ImportExportModelAdmin):
    list_display = ("name", "desc")
    list_display_links = ("name", "desc")
    search_fields = (''name'', ''desc'')
    model_icon = "fa fa-tag"
    list_per_page = 50
    resource_class = commodityResource

    def save_model(self, request, obj, form, change):
        super().save_model(request, obj, form, change)

运行效果图如下:

 

点击导入页面如下:

实现思路如下:

通过重写导入页面,在应用目录(app)下-->templatetags-->apptags.py

配置settings.py

libraries 节点

TEMPLATES = [
    {
        ''BACKEND'': ''django.template.backends.django.DjangoTemplates'',
        ''DIRS'': [os.path.join(BASE_DIR, ''templates'')]
        ,
        ''APP_DIRS'': True,
        ''OPTIONS'': {
            ''context_processors'': [
                ''django.template.context_processors.debug'',
                ''django.template.context_processors.request'',
                ''django.contrib.auth.context_processors.auth'',
                ''django.contrib.messages.context_processors.messages'',
            ],
            ''libraries'': {
                ''apptags'': ''app.templatetags.apptags''
            },
        },
    },
]

apptags.py

from django import template
from django.apps import apps

register = template.Library()  # 这一句必须这样写

@register.simple_tag(takes_context=True)
def import_head_tag(context):
    verbose_names = []
    fieldlists = context.dicts[3]["fields"]
    opts = str(context.dicts[3]["opts"]).split(".")
    for f in fieldlists:
        fields = apps.get_model(opts[0], opts[1])._meta.fields
        for fs in fields:
            if (str(fs).split(".")[-1] == str(f)):
                verbose_names.append(fs.verbose_name)
                break

    return "".join(verbose_names)

重写django-import-export 导入页面,在项目templates下新建 admin-->import_export--> import.html 

import.html代码如下  将{{ fields|join:", " }}  替换成 apptags.py 定义的 import_head_tag 方法即可

{% extends "admin/import_export/base.html" %}
{% load static simpletags apptags %}
{% load i18n %}
{% load admin_urls %}
{% load import_export_tags %}
{% load static %}

{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "import_export/import.css" %}" />{% endblock %}

{% block breadcrumbs_last %}
{% trans "Import" %}
{% endblock %}

{% block content %}

  {% if confirm_form %}
    <form action="{% url opts|admin_urlname:"process_import" %}" method="POST">
      {% csrf_token %}
      {{ confirm_form.as_p }}
      <p>
        {% trans "Below is a preview of data to be imported. If you are satisfied with the results, click ''Confirm import''" %}
      </p>
      <div class="submit-row">
        <input type="submit" class="default" name="confirm" value="{% trans "Confirm import" %}">
      </div>
    </form>
  {% else %}
    <form action="" method="post" enctype="multipart/form-data">
      {% csrf_token %}

      <p>
        {% trans "This importer will import the following fields: " %}
        <code>{% import_head_tag %} </code>

      </p>

      <fieldset class="module aligned">
        {% for field in form %}
          <div class="form-row">
            {{ field.errors }}

            {{ field.label_tag }}

            {{ field }}

            {% if field.field.help_text %}
            <p class="help">{{ field.field.help_text|safe }}</p>
            {% endif %}
          </div>
        {% endfor %}
      </fieldset>

      <div class="submit-row"><input type="submit" class="default" value="{% trans "Submit" %}">
      </div>
    </form>
  {% endif %}

  {% if result %}

    {% if result.has_errors %}

      <h2>{% trans "Errors" %}</h2>
      <ul>
        {% for error in result.base_errors  %}
        <li>
          {{ error.error }}
          <div class="traceback">{{ error.traceback|linebreaks }}</div>
        </li>
        {% endfor %}
        {% for line, errors in result.row_errors %}
          {% for error in errors %}
            <li>
              {% trans "Line number" %}: {{ line }} - {{ error.error }}
              <div><code>{{ error.row.values|join:", " }}</code></div>
              <div class="traceback">{{ error.traceback|linebreaks }}</div>
            </li>
          {% endfor %}
        {% endfor %}
      </ul>

    {% elif result.has_validation_errors %}

      <h2>{% trans "Some rows failed to validate" %}</h2>
        
      <p>{% trans "Please correct these errors in your data where possible, then reupload it using the form above." %}</p>
      
      <table class="import-preview">
        <thead>
          <tr>
            <th>{% trans "Row" %}</th>
            <th>{% trans "Errors" %}</th>
            {% for field in result.diff_headers %}
              <th>{{ field }}</th>
            {% endfor %}
          </tr>
        </thead>
        <tbody>
        {% for row in result.invalid_rows %}
          <tr>
            <td>{{ row.number }} </td>
            <td class="errors">
              <span class="validation-error-count">{{ row.error_count }}</span> 
              <div class="validation-error-container">
                <ul class="validation-error-list">
                  {% for field_name, error_list in row.field_specific_errors.items %}
                    <li>
                        <span class="validation-error-field-label">{{ field_name }}</span>
                        <ul>
                          {% for error in error_list %}
                            <li>{{ error }}</li>
                          {% endfor %}
                        </ul>
                    </li>
                  {% endfor %}
                  {% if row.non_field_specific_errors %}
                    <li>
                      <span class="validation-error-field-label">{% trans "Non field specific" %}</span>
                      <ul>
                        {% for error in row.non_field_specific_errors %}
                          <li>{{ error }}</li>
                        {% endfor %}
                      </ul>
                    </li>
                  {% endif %}
                </ul>
              </div>
            </td>
            {% for field in row.values %}
              <td>{{ field }}</td>
            {% endfor %}
          </tr>
        {% endfor %}
        </tbody>
      </table>
  
    {% else %}

      <h2>{% trans "Preview" %}</h2>

      <table class="import-preview">
        <thead>
          <tr>
            <th></th>
            {% for field in result.diff_headers %}
              <th>{{ field }}</th>
            {% endfor %}
          </tr>
        </thead>
        {% for row in result.valid_rows %}
          <tr>
            <td class="import-type">
              {% if row.import_type == ''new'' %}
                {% trans "New" %}
              {% elif row.import_type == ''skip'' %}
                {% trans "Skipped" %}
              {% elif row.import_type == ''delete'' %}
                {% trans "Delete" %}
              {% elif row.import_type == ''update'' %}
                {% trans "Update" %}
              {% endif %}
            </td>
            {% for field in row.diff %}
              <td>{{ field }}</td>
            {% endfor %}
          </tr>
        {% endfor %}
      </table>

    {% endif %}

  {% endif %}
{% endblock %}

修改后的效果

 

关于django-import-export:实例数据在保存后种族条件未更新的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于Django import / export实现数据库导入导出、django import和django-import-export、Django 调用报错 " ImportError: Couldn''t import Django. "、django-import-export 显示model verbose_name的相关知识,请在本站寻找。

本文标签: