Exporting items from a model to CSV Django / Python

前端 未结 9 2040
死守一世寂寞
死守一世寂寞 2021-02-03 09:52

I\'m fairly new to django and Python and want to be able to export a list of items in my model i.e products. I\'m looking at the documentation here - https://docs.djangoproject.

相关标签:
9条回答
  • 2021-02-03 10:27

    Here is a potential solution, based on @tomasz-gandor 's answer, but updated to 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])
    

    Can easily be used with:

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

    0 讨论(0)
  • 2021-02-03 10:28

    Using django.db.models.query.QuerySet.values results in more optimised queries for my use case.

    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
    
    0 讨论(0)
  • 2021-02-03 10:29

    I use this on my code. A function called from view. It automatically get model fields to make columns. You can also customize the field list you want to export.

    Function

    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
    

    Usage

    @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",
            ]
            )
    

    Original answer

    It works, and it needs only to define model class in model_class variable. This Django view let use downloads CSV. CSV name is 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
    
    0 讨论(0)
  • 2021-02-03 10:33

    If you don't care about fieldnames and want all the fields, just do this.

    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)
    
    0 讨论(0)
  • 2021-02-03 10:34

    I combined some of the previous answers, because I needed to import some data from production and change some of it along the way. So here is my solution, which you can use to override some field values while writing the CSV file.

    Export some queryset data into CSV file:

    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)
    
    0 讨论(0)
  • 2021-02-03 10:39

    Depending on the scenario - you may want to have a CSV of your model. If you have access to the Django Admin site, you can plug in a generic action for any model displayed as a list (google: django admin actions)

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

    If you're operating with a console (python manage.py ...), you can use such a script, which I just used:

    (place it in: 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])
    

    This does not catch any exceptions etc., but as an Admin you won't cause them to be raised, right?

    Use it like:

    ./manage.py model2csv my_ecommerce.Product > products.csv
    
    0 讨论(0)
提交回复
热议问题