12

我对 django 和 Python 还很陌生,希望能够在我的模型(即产品)中导出项目列表。我在这里查看文档 - https://docs.djangoproject.com/en/dev/howto/outputting-csv/

我假设我需要创建一个变量来存储我想要的所有数据。但不确定它在上面链接的代码片段中的位置。

道歉,因为这是一个非常愚蠢的问题,但真的会有所帮助。

到目前为止,这是我的脚本的代码:

import csv

from products.models import Product

from django.http import HttpResponse


def export_to_csv(request):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="mytest.csv"'
4

10 回答 10

17

看看python csv 模块

您可能希望获得模型字段

def get_model_fields(model):
    return model._meta.fields

然后使用

getattr(instance, field.name)

获取字段值(如this question)。

然后你会想要类似的东西

with open('your.csv', 'wb') as csvfile:
    writer = csv.writer(csvfile)
    # write your header first
    for obj in YourModel.objects.all():
        row = ""
        for field in fields:
             row += getattr(obj, field.name) + ","
        writer.writerow(row)

它有点冗长(并且未经测试),但它应该给你一个想法。(哦,别忘了关闭你的文件)

于 2013-02-22T17:14:33.820 回答
14

根据场景 - 您可能希望拥有模型的 CSV。如果您有权访问 Django 管理站点,则可以为任何显示为列表的模型插入通用操作(谷歌:django 管理操作)

http://djangosnippets.org/snippets/790/

如果您使用控制台 ( python manage.py ...) 进行操作,则可以使用我刚刚使用的这样一个脚本:

(把它放在:yourapp/management/commands/model2csv.py)

"""
 Prints CSV of all fields of a model.
"""

from django.core.management.base import BaseCommand, CommandError
import csv
import sys

class Command(BaseCommand):
    help = ("Output the specified model as CSV")
    args = '[appname.ModelName]'

    def handle(self, *app_labels, **options):
        from django.db.models import get_model
        app_name, model_name = app_labels[0].split('.')
        model = get_model(app_name, model_name)
        field_names = [f.name for f in model._meta.fields]
        writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL)
        writer.writerow(field_names)
        for instance in model.objects.all():
            writer.writerow([unicode(getattr(instance, f)).encode('utf-8') for f in field_names])

这不会捕获任何异常等,但是作为管理员,您不会引发它们,对吗?

像这样使用它:

./manage.py model2csv my_ecommerce.Product > products.csv
于 2013-05-20T20:27:17.560 回答
3

您还可以制作模板来帮助格式化!

模板是常见的 Django 模板

from django.template import loader
def export_to_csv(request):
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename="products-list.csv"'
    template = loader.get_template('templates/products_template.csb')
    response.write(template.render(Context({'products': Products.objects.all()})))
    return response
于 2013-02-22T17:47:49.397 回答
3

我在我的代码上使用它。从视图调用的函数。它会自动获取模型字段以创建列。您还可以自定义要导出的字段列表。

功能

import csv

from django.http import HttpResponse

from .models import Books


def export_qs_to_csv(model_class = None, qs = None, field_names = None):
    if model_class and not qs:
        qs = model_class.objects.all()
    if qs and not model_class:
        model_class = qs.model

    meta = model_class._meta
    if not field_names:
        field_names = [field.name for field in meta.fields]

    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta)
    writer = csv.writer(response)

    writer.writerow(field_names)
    for obj in qs:
        row = writer.writerow([getattr(obj, field) for field in field_names])

    return response

用法

@user_passes_test(lambda u: u.is_superuser)
def export_books(request):
    return export_qs_to_csv(model_class = Books)
    # or
    return export_qs_to_csv(qs = Books.objects.filter(published = True))
    # or
    return export_qs_to_csv(
        qs = Books.objects.filter(published = True),
        field_names = [
            "title",
            "price",
            "publishing_date",
        ]
        )

原始答案

它可以工作,它只需要在model_class变量中定义模型类。这个 Django 视图让我们使用下载 CSV。CSV 名称是Django_app.model_name.csv

import csv

from django.http import HttpResponse

from .models import Trade


def export_to_csv(request):
    # The only line to customize
    model_class = Trade

    meta = model_class._meta
    field_names = [field.name for field in meta.fields]

    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta)
    writer = csv.writer(response)

    writer.writerow(field_names)
    for obj in model_class.objects.all():
        row = writer.writerow([getattr(obj, field) for field in field_names])

    return response
于 2019-01-09T23:38:08.503 回答
3

使用django.db.models.query.QuerySet.values可以为我的用例带来更优化的查询。

import csv
from datetime import datetime

from django.http import HttpResponse

# Populate this list with your model's fields
# Replace MODEL with your model
fields = [f.name for f in MODEL._meta.fields]

# The following code will live inside your view
timestamp = datetime.now().isoformat()

response = HttpResponse(content_type="text/csv")
response[
    "Content-Disposition"
] = f"attachment; filename={timestamp}.csv"
writer = csv.writer(response)

# Write the header row
writer.writerow(fields)

# Replace MODEL with your model
for row in MODEL.objects.values(*fields):
    writer.writerow([row[field] for field in fields])

return response
于 2019-10-28T09:52:38.563 回答
1

这是一个潜在的解决方案,基于 @tomasz-gandor 的回答,但更新到 2020 年:

"""
 Prints CSV of all fields of a model.
"""

import csv
from django.core.management.base import BaseCommand, CommandError


class Command(BaseCommand):
    help = ("Output the specified model as CSV")


    def add_arguments(self, parser):
        parser.add_argument('model',
                            nargs=1,
                            type=str,
                            help='Model name to export, like <app.model> or "members.Member"')
        parser.add_argument('outfile',
                            nargs=1,
                            type=str,
                            help='Save path, like </path/to/outfile.csv> or "/data/members.csv"')


    def handle(self, *app_labels, **options):
        from django.apps import apps
        app_name, model_name = options['model'][0].split('.')
        model = apps.get_model(app_name, model_name)
        field_names = [f.name for f in model._meta.fields]
        writer = csv.writer(open(options['outfile'][0], 'w'), quoting=csv.QUOTE_ALL, delimiter=',')
        writer.writerow(field_names)
        for instance in model.objects.all():
            writer.writerow([str(getattr(instance, f)) for f in field_names])

可以很容易地用于:

python manage.py model2csv members.Member /data/members_export.csv

于 2020-06-30T23:35:20.527 回答
0

我使用了 django-queryset-csv 包。

按着这些次序:

  1. pip install django-queryset-csv

  2. 你的意见.py:

import djqscsv
from products.models import Product

def get_csv(request):
    qs = Product.objects.all()
    return djqscsv.render_to_csv_response(qs)
于 2021-05-03T16:18:26.347 回答
0

将此解决方案用于模型 csv 文件。可能会有所帮助

 # Create the HttpResponse object with the appropriate CSV header.
 response = HttpResponse(content_type='text/csv')
 response['Content-Disposition'] = 'attachment; 
 filename="somefilename.csv"'
 writer = csv.writer(response);
 writer.writerow(["username","Email"]);
 for i in User.objects.all():
     writer.writerow([i.username,i.email])
 return response
于 2020-08-20T08:16:17.130 回答
0

我结合了之前的一些答案,因为我需要从生产中导入一些数据并在此过程中对其进行一些更改。所以这是我的解决方案,您可以在编写 CSV 文件时使用它来覆盖某些字段值。

将一些查询集数据导出到 CSV 文件中:

import csv

from myapp.models import MyModel
from user.models import User

# Make some queryset manually using Django shell:
user = User.objects.get(username='peterhil')
queryset = MyModel.objects.filter(user=user)

def query_to_csv(queryset, filename='items.csv', **override):
    field_names = [field.name for field in queryset.model._meta.fields]
    def field_value(row, field_name):
        if field_name in override.keys():
            return override[field_name]
        else:
            return row[field_name]
    with open(filename, 'w') as csvfile:
        writer = csv.writer(csvfile, quoting=csv.QUOTE_ALL, delimiter=',')
        writer.writerow(field_names)  # write the header
        for row in queryset.values(*field_names):
            writer.writerow([field_value(row, field) for field in field_names])

# Example usage:
query_to_csv(queryset, filename='data.csv', user=1, group=1)
于 2020-08-03T11:46:50.680 回答
0

如果您不关心字段名并想要所有字段,请执行此操作。

with open('file_name.csv', 'w') as csvfile:
    writer = csv.writer(csvfile)
    for obj in YourModel.objects.values_list():
        row = list(obj)
        writer.writerow(row)
于 2020-12-14T07:49:16.067 回答