Bienvenida

1

Todo lo que aprenderás sobre Django

Cimientos

2

Arquitectura de una aplicación

3

The Twelve-Factor App

4

Codebase: Settings modular

5

Codebase: Dependencias y archivos de docker

6

Codebase: Docker

7

Setups alternativos

Modelos

8

Herencia de modelos

9

Proxy models

10

App de usuarios

11

Organizando modelos en un paquete de Django

12

Creando el modelo de perfil de usuario

13

Solución del reto: arreglando la migración de users a user

14

Aplicación y modelo de círculos

15

Migraciones y admin de círculos

Introducción a Django REST Framework

16

Aprende cómo construir tu propio API con Django Rest Framework

17

Vistas, URLs y Parsers de DRF

18

Serializers

19

Buenas prácticas para el diseño de un API REST

20

Request, response, renderers y parsers

Real DRF

21

Autenticación y tipos de autenticación

22

APIView

23

Creando el token de autorización

24

User sign up

25

Limitar login a usuarios con cuenta verificada

26

Configurar envío de email

27

Instalar PyJWT y generar tokens

28

Verificar cuenta usando JWT

29

Actualizar modelo de circle (membership)

30

Crear CircleViewSet

31

Añadiendo autorización y paginación

32

Creación de circulos

33

Update de círculo, custom permissions y DRF Mixins

34

Migración de vistas de usuarios a ViewSets

35

Detalle de usuario

36

Update profile data

37

List members - Recursos anidado

38

Retrieve destroy member

39

Modelo de invitaciones y manager

40

Obtener invitaciones de un miembro

41

Unirse a grupo

42

Filtrado

43

App de rides y modelos

44

Implementar la publicación de un ride

45

Validación de campos de un serializer

46

Listado de rides

47

Editar un ride

48

Unirse a viaje

49

Terminar viaje

50

Calificar viaje

Tareas asíncronas

51

¿Qué es Celery?

52

Creando tarea asíncrona

53

Creando tarea periódica

Testing

54

Python unittest y Django TestCase

55

DRF APITestCase

Django Admin

56

Admin actions: Modificar datos de un query

57

Admin actions: Regresando una respuesta HTTP

Deployment

58

Instalación de la aplicación

59

Configuración del dominio en Mailgun y del Bucket en Amazon S3

60

Configuración final de Docker Container usando Supervisor

61

Tutorial de despliegue de la aplicación

62

Futuros pasos y cierre del curso

Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Migraciones y admin de círculos

15/62
Recursos

Aportes 43

Preguntas 4

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Para importar cosas de un archivo csv (gracias, curso de Python3):

import csv

def import_csv(csv_filename):
    with open(csv_filename, mode='r') as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            circle = Circle(**row)
            circle.save()
            print(circle.name)

Una forma sencilla de precargar datos es usando fixtures

Dentro del directorio circles tiene que crear el directorio fixtures y crear un archivo en formato JSON (circles.json por ejemplo) con la info que esta abajo y luego, desde el terminal tienen que correr el comando loaddata:

docker-compose run --rm django python manage.py loaddata cride/circles/fixtures/circles.json

circles.json

[
    {
        "model": "circles.circle",
        "pk": 1,
        "fields": {
            "name": "Facultad de Ciencias, UNAM",
            "slug_name": "unam-fciencias",
            "is_public": 1,
            "verified": 1,
            "members_limit": 0,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 2,
        "fields": {
            "name": "Tec de Monterrey, Campos Santa Fé",
            "slug_name": "itesm-csf",
            "is_public": 1,
            "verified": 1,
            "members_limit": 0,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 3,
        "fields": {
            "name": "Inventive",
            "slug_name": "inventive",
            "is_public": 0,
            "verified": 1,
            "members_limit": 30,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 4,
        "fields": {
            "name": "Platzi Bogotá",
            "slug_name": "platzi-bog",
            "is_public": 0,
            "verified": 1,
            "members_limit": 120,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 5,
        "fields": {
            "name": "Platzi México",
            "slug_name": "platzi-mex",
            "is_public": 0,
            "verified": 1,
            "members_limit": 30,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 6,
        "fields": {
            "name": "Google México",
            "slug_name": "google-mx",
            "is_public": 0,
            "verified": 1,
            "members_limit": 250,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 7,
        "fields": {
            "name": "Curso de Fotografía, UVA",
            "slug_name": "curso-foto-uva",
            "is_public": 1,
            "verified": 0,
            "members_limit": 25,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 8,
        "fields": {
            "name": "Equipo de futbol, chapinero",
            "slug_name": "fut-chapinero",
            "is_public": 1,
            "verified": 0,
            "members_limit": 40,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 9,
        "fields": {
            "name": "Grupo 3340, Prácticas de campo",
            "slug_name": "grupo-3340-campo",
            "is_public": 1,
            "verified": 0,
            "members_limit": 50,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 10,
        "fields": {
            "name": "Generación 2018 Escuela de enfermería",
            "slug_name": "enfermeria-2018",
            "is_public": 1,
            "verified": 0,
            "members_limit": 0,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 11,
        "fields": {
            "name": "Facultad de Ingeniería, UNAM",
            "slug_name": "unam-fi",
            "is_public": 1,
            "verified": 1,
            "members_limit": 0,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 12,
        "fields": {
            "name": "Facultad de Medicina, UNAM",
            "slug_name": "unam-fm",
            "is_public": 1,
            "verified": 1,
            "members_limit": 0,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 13,
        "fields": {
            "name": "Platzi Developer Circle - Bogotá",
            "slug_name": "platzi-dev",
            "is_public": 1,
            "verified": 0,
            "members_limit": 0,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 14,
        "fields": {
            "name": "Platzi Developer Circle - CDMX",
            "slug_name": "platzi-dev-mx",
            "is_public": 1,
            "verified": 0,
            "members_limit": 0,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 15,
        "fields": {
            "name": "IBM Santa Fé",
            "slug_name": "ibm-santafe",
            "is_public": 0,
            "verified": 1,
            "members_limit": 0,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 16,
        "fields": {
            "name": "P&G - Santa Fé",
            "slug_name": "p-n-g",
            "is_public": 1,
            "verified": 0,
            "members_limit": 1000,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 17,
        "fields": {
            "name": "Amigos de Centraal",
            "slug_name": "comunidad-centraal",
            "is_public": 1,
            "verified": 0,
            "members_limit": 0,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 18,
        "fields": {
            "name": "Central Academy",
            "slug_name": "centraal-academy",
            "is_public": 1,
            "verified": 1,
            "members_limit": 0,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 19,
        "fields": {
            "name": "Estado de México - CDMX",
            "slug_name": "edomex",
            "is_public": 1,
            "verified": 0,
            "members_limit": 0,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 20,
        "fields": {
            "name": "Satelite - Santa Fé entre semana",
            "slug_name": "sat-sfe-week",
            "is_public": 1,
            "verified": 0,
            "members_limit": 0,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    },
    {
        "model": "circles.circle",
        "pk": 21,
        "fields": {
            "name": "Sable Digital",
            "slug_name": "sable",
            "is_public": 0,
            "verified": 0,
            "members_limit": 30,
            "created": "2019-08-31",
            "modified": "2019-08-31"
        }
    }
]

De esta forma se evita tener que crear una funcion para leer el csv e importar la data y el comando loaddata se podria agregar al Dockerfile para que se ejecute al correr el comando build de Docker.

Codigo para importar Circulos desde shell_plus

circles = [
    ["Facultad de Ciencias, UNAM","unam-fciencias",1,1,0],
    ["Tec de Monterrey, Campos Santa Fé","itesm-csf",1,1,0],
    ["Inventive","inventive",0,1,30],
    ["Platzi Bogotá","platzi-bog",0,1,120],
    ["Platzi México","platzi-mex",0,1,30],
    ["Google México","google-mx",0,1,250],
    ["Curso de Fotografía, UVA","curso-foto-uva",1,0,25],
    ["Equipo de futbol, chapinero","fut-chapinero",1,0,40],
    ["Grupo 3340, Prácticas de campo","grupo-3340-campo",1,0,50],
    ["Generación 2018 Escuela de enfermería","enfermeria-2018",1,0,0],
    ["Facultad de Ingeniería, UNAM","unam-fi",1,1,0],
    ["Facultad de Medicina, UNAM","unam-fm",1,1,0],
    ["Platzi Developer Circle - Bogotá","platzi-dev",1,0,0],
    ["Platzi Developer Circle - CDMX","platzi-dev-mx",1,0,0],
    ["IBM Santa Fé","ibm-santafe",0,1,0],
    ["P&G - Santa Fé","p-n-g",1,0,1000],
    ["Amigos de Centraal","comunidad-centraal",1,0,0],
    ["Central Academy","centraal-academy",1,1,0],
    ["Estado de México - CDMX","edomex",1,0,0],
    ["Satelite - Santa Fé entre semana","sat-sfe-week",1,0,0],
    ["Sable Digital","sable",0,0,30],
]
for cirlce in circles:
    name = cirlce[0]
    slug_name = cirlce[1]
    is_public = cirlce[2]
    verified = cirlce[3]
    members_limit = cirlce[4]
    print(f'Processed { name } { slug_name } { is_public } { verified } { members_limit }')
    Circle.objects.create(
        name=name,
        slug_name=slug_name,
        is_public=is_public,
        verified=verified,
        members_limit=members_limit,
    )
 def load_circles():
	with open('circles.csv') as csv_file:
		csv_reader = csv.DictReader(csv_file)
                line_count = 0
                for row in csv_reader:
                	circles = Circle(
    			name = row["name"],
			slug_name = row["slug_name"],
			is_public = row["is_public"],
 			verified = row["verified"],
			members_limit = row["members_limit"])
			circles.save()
			name = row["name"]
 			print(f'{name} ha sido guardado satisfactoriamente')
 			line_count += 1
		print(f'Han finalizado la carga con un total de {line_count}')

Mi versión de import_data

def import_data(file): 
     with open(file, 'r') as f: 
         content = list(csv.reader(f)) 
         for circle in content[1:]: 
             Circle(name=circle[0], 
                 slug_name=circle[1], 
                 is_public=circle[2], 
                 verified=circle[3], 
                 members_limit=circle[4] 
             ).save() 

En caso de que django no detecte la migración inicial, hay que especificar el nombre de la aplicación:
docker-compose run --rm django python manage.py makemigrations circles

Hola, me sale este error, aver si alguien me pudiera ayudar:
File “/usr/local/lib/python3.6/site-packages/django_extensions/management/commands/shell_plus.py”, line 11, in <module>
from django.utils.six import PY3
ModuleNotFoundError: No module named ‘django.utils.six’

TRY ME!!!
Copia y pega el siguiente código en el shell_plus de django. O bien impórtalo para traer directamente del gist de Pablo Trinidad los datos de los círuclos.

Puedes copiar el código desde aquí abajo o de mi gist. Saludos.

Código

"""Get data circles directly from Pablo Trinidad gist
and insert data in Circle Model."""


from os import system

# Success code for linux terminal is equal to 0.
request_install = system("pip install requests")

if not request_install:
    import requests

    circles_url_raw_data = "https://gist.githubusercontent.com/pablotrinidad/93ee462e0ee761bd505f0a2fed3d1c8c/raw/61f02a79080586901d0c9b510d4c4d2fff7f3836/circles.csv"
    response = requests.get(circles_url_raw_data)
    if response.status_code == 200:
        datas_raw = response.text
        datas_list = [data.split(',') for data in datas_raw.split('\n')]
        for data in datas_list:
            Circle.objects.update_or_create(
                name=data[0],
                slug_name=data[1],
                defaults={
                    'is_public': bool(data[2]),
                    'verified': bool(data[3]),
                    'members_limit': int(data[4]) if data[4].isnumeric() else 0,
                },
            )
    else:
        print('ERROR: conexion.')
else:
    print('ERROR: problem on installation "requests" package.')```

El modelo Circles al heredar el meta de CRideModel, heredaría lo de abstract=True??

Django import export es una librería muy útil también para poder importar los datos desde el admin.

Django import export

¡¡¡¡TRY WITH THIS!!!
this function not only works with the pablo file. work with any csv you want to import. You just need the column name in csv be the same that the fields in the model.

def import_circles(file):
         with open(file) as csv_file:
             csv_reader = csv.reader(csv_file)
             headers = next(csv_reader)
             for row in csv_reader:
                 b = Circle()
                 for idx,val in enumerate(row):
                     setattr(b, headers[idx], val)
                 b.save()
                 print(f'saved circle instance with name ${b}')

Para los que les da un error al ejecutar el shell_plus, deben:

  1. cambiar la versión a django-extensions==3.0.9 en los requerimientos local.
  2. matar todos los servicios, volver a construir las imagenes y levantar nuevamente los servicios.
  3. ahora si ejecutan el comando de shell_plus

Aca les dejo mi “solucion”:

def import_circle_to_csv(path: str):
    import csv
    with open(path) as csv_file:
        circles = [Circle(**attrs) for attrs in csv.DictReader(csv_file)]

    Circle.objects.bulk_create(circles)
    for circle in circles:
        print(f'circle saved success: {circle}')

En hype por el shell_plus!

Este es mi codido para importar

import csv

def import_circle(file):
   with open(file) as csvfile:
       reader = csv.DictReader(csvfile)
       for row in reader:
           p = Circle(name=row['name'], slug_name=row['slug_name'], is_public=row['is_public'], verified=row['verified'], membert=row['membert'])
           p.save()
Hola a todos, Tengo un sistema con millones de registros en una tabla, quiero hacer un reporte pero consultando la base de datos directamente tarda demasiado, es un reporte con agrupamientos y Joins, alguien sabe ¿que arquitectura debo usar para generará reportes grandes?, estaba pensando en usar decir como una especie de espejo, pero la verdad no tengo idea de cómo se resuelve esto, me ayudan por favor. Saludos.

Aquí mi solución:

import csv

def import_csv(filename):
    with open(filename) as f:
        reader = csv.DictReader(f)
        circles_list = [
            Circle(
                name=line['name'],
                slug_name=line['slug_name'],
                is_public=int(line['is_public']),
                verified=int(line['verified']),
                members_limit=line['members_limit'],
                is_limited=True if int(line['members_limit']) > 0 else False,
        )
        for line in reader
        ]
        Circle.objects.bulk_create(circles_list)

Para los que le salgan un error así, cuando estan dentro de la consola de de shell_plus

 File "/usr/local/lib/python3.6/site-packages/prompt_toolkit/completion/base.py", line 198, in get_completions_async
    for item in self.get_completions(document, complete_event):
  File "/usr/local/lib/python3.6/site-packages/IPython/terminal/ptutils.py", line 116, in get_completions
    print_tb(e)
  File "/usr/local/lib/python3.6/traceback.py", line 53, in print_tb
    print_list(extract_tb(tb, limit=limit), file=file)
  File "/usr/local/lib/python3.6/traceback.py", line 72, in extract_tb
    return StackSummary.extract(walk_tb(tb), limit=limit)
  File "/usr/local/lib/python3.6/traceback.py", line 345, in extract
    for f, lineno in frame_gen:
  File "/usr/local/lib/python3.6/traceback.py", line 310, in walk_tb
    yield tb.tb_frame, tb.tb_lineno
AttributeError: 'TypeError' object has no attribute 'tb_frame'

If you suspect this is an IPython 7.16.1 bug, please report it at:
    https://github.com/ipython/ipython/issues
or send an email to the mailing list at [email protected]

You can print a more detailed traceback right now with "%tb", or use "%debug"
to interactively debug it.

Extra-detailed tracebacks for bug-reporting purposes can be enabled via:
    %config Application.verbose_crash=True 

Agreguen en requirements/local.txt


# Tools
django-extensions==3.1.2
jedi==0.17.2

Aquí esta la documentación de dajngo-extension, Hay una parte muy interesate y es que tienen un runserver, donce se puede hacer debbuging y todo, se lo recomiendo.
https://github.com/django-extensions/django-extensions

Cuando se ejecuta

docker-compose run --rm django python manage.py shell_plus

aparece errores, eso debido a que están usando una versión anterior de django-extensions. Para solucionar deben ir a la carpeta requirements/local.txt
#Tools
django-extensions==3.1.3 #cambiar por esta nueva versión
Deben construir nuevamente:
docker-compose build

Asi quedo mi codigo/ resultado, basado en los demas aportes

<def import_csv(csv_filename):
    with open(csv_filename, mode='r') as f:
        reader = csv.DictReader(f)
        for row in reader:
            circle = Circle(**row)
            if int(circle.members_limit) > 0:
                circle.is_limited =  True
                circle.save()
                print(circle.name + ' ' + str(circle.is_limited) )
            else:
                circle.is_limited = False
                circle.save()
                print(circle.name + ' ' + str(circle.is_limited) )
code> 

Pasos para cargar el archivo: 😃
Asegurate de tener el archivo con el nombre de circles.csv dentro de la carpeta en donde estas ejecutando el script

docker-compose run --rm django python manage.py shell_plus

import csv

def import_data(file):
    with open(str(file)) as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=',')
        line_counter = 0
        for row in csv_reader:
            if line_counter != 0:
                c = Circle(
                    name=row[0],
                    slug_name=row[1],
                    is_public=(False if int(row[2]) == 0 else True),
                    verified=(False if int(row[3]) == 0 else True),
                    members_limit=int(row[4])
                )
                c.save()
            line_counter += 1

import_data('circles.csv')

Insertar datos desde csv

import csv
def import_data(csvfile):
    with open(csvfile, "r") as f:
        dreader = csv.DictReader(f)
            for row in dreader:
                Circle.objects.create(name=row['name'],slug_name=row['slug_name'],is_public=row['is_public'],verified=row['verified'],members_limit=row['members_limit'])
                print(row[name])

import_data('circles.csv')
import csv
circles_list = []
with open('circles.csv') as csv_file:
    csv_reader = csv.reader(csv_file, delimiter=',')
    next(csv_reader)
    data = list(csv_reader)
    for row in data:
        if len(row[0]) == 0:
            break
        is_public = row[2]
        verified = row[3]
        if verified == 0:
            verified = False
        else:
            verified = True
        if is_public == 0:
            is_public = False
        else:
            is_public = True
        circles_list.append(
            Circle(
                name=row[0],
                slug_name=row[1],
                is_public=is_public,
                verified=verified,
                members_limit=row[4]
            )
        )
    Circle.objects.bulk_create(circles_list)

Importar los datos desde un csv

import csv

def import_circle_data(filename):
with open(filename, mode='r') as data:
    reader = csv.DictReader(data)
    for row in reader:
        circle = Circle(**row)
        if int(circle.members_limit)>0:
            circle.is_limited = True
        circle.save()
        print(circle.name)

Eh aqui mi respuesta 😮

import csv
def import_data(file):
    ...:     with open(str(file)) as csv_file:
    ...:         csv_reader = csv.reader(csv_file, delimiter=",")
    ...:         line_counter = 0
    ...:         for row in csv_reader:
    ...:             if line_counter != 0:
    ...:                 c = Circle(
    ...:                     name=row[0],
    ...:                     slug_name=row[1],
    ...:                     is_public=row[2],
    ...:                     verified=row[3],
    ...:                     members_limit=int(row[4]))
    ...:                 if c.members_limit > 0:
    ...:                     c.is_limited=True
    ...:                 c.save()
    ...:             line_counter += 1

intente hacerlo lo mas sencillo posible

Generalmente siempre uso IPython, pero me parece mucho mejor ese shell_plus de Django_extension!

Aqui mi función

import csv

def import_csv(filename): 
    with open(filename) as csvarchivo:
        entrada=csv.DictReader(csvarchivo)
        for reg in entrada:
            if int(reg['members_limit'])!=0:
                Circle.objects.create( 
                name=reg['name'], 
                slug_name=reg['slug_name'], 
                is_public=reg['is_public'], 
                verifed=reg['verifed'], 
                is_limited=1, 
                members_limit=reg['members_limit']) 
                print(reg['name']) 
            else:
                Circle.objects.create( 
                name=reg['name'], 
                slug_name=reg['slug_name'], 
                is_public=reg['is_public'], 
                verifed=reg['verifed'],  
                members_limit=reg['members_limit']) 
                print(reg['name'])

Tengo una duda, si no tuviera los datos que da el profesor en su archivo, existe alguna forma de crear datos aleatorios para llenar la base de datos sin tener que agregar uno por uno?

Los servidores de Docker y Django (por separado) estan corriendo si error. Al usar el comando;

docker-compose run --rm django python manage.py shell_plus

(Incluso sin el shell_plus)

me muestra lo siguiente:

Starting cride-platzi-5-profile-model_postgres_1 ... done
PostgreSQL is available
\entrypoint: exec; line 43: python: not found

Alguna sugerencia?

Importar los archivos

import csv

def import_data(file):
    with open(str(file)) as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=',')
        line_counter = 0
        for row in csv_reader:
            if line_counter != 0:
                c = Circle(
                    name=row[0],
                    slug_name=row[1],
                    rides_offerted=int(row[2]),
                    rides_taken=int(row[3]),
                    is_limited=(False if int(row[4]) == 0 else True),
                    members_limit=int(row[4])
                )
                c.save()
        line_counter += 1

import_data('circles.csv')

Hola este fue mi código:

# General
import csv
import random
import string

# Models
from cride.circles.models import Circle


def random_about(N):
    """
    This function create a random about, it's base it in
    https://stackoverflow.com/questions/2257441/random-string-generation-with-upper-case-letters-and-digits
    :return: str[N]
    """
    about = """Lorem Ipsum is simply dummy text of the printing and typesetting
    industry. Lorem Ipsum has been the industry's standard dummy text ever
    since the 1500s, when an unknown printer took a galley of type and scrambled
    it to make a type specimen book. It has survived not only five centuries,
    but also the leap into electronic typesetting, remaining essentially unchanged.
    It was popularised in the 1960s with the release of Letraset sheets containing Lorem
    Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker
    including versions of Lorem Ipsum."""
    first = random.randint(0, N)
    last = (first + N) % len(about)
    return about[first:last]


def load_data_from_csv_to_circles(file_name):
    """
    This function upload data from csv to the circles table in the data base
    :param file_name: str name of the csv
    :return: none
    """

    with open(file_name, 'r') as file:
        reader = csv.DictReader(file)

        for row in reader:
            members_limit = int(row['members_limit'])
            if members_limit > 0:
                is_limited = True
            else:
                is_limited = False

            about = random_about(100)

            data = {
                'name': row['name'],
                'slug_name': row['slug_name'],
                'about': about,
                'picture': '',
                'rides_offered': 0,
                'rides_taken': 0,
                'verified': row['verified'],
                'is_public': row['is_public'],
                'is_limited': is_limited,
                'members_limit': members_limit
            }
            c = Circle.objects.create(**data)

Les comparto mi solución:

import csv

def load_data(filename):
	with open(filename) as f: 
		reader = csv.DictReader(f) 
		for row in reader: 
			circle = Circle(
				name=str(row['name']),
				slug_name=str(row['slug_name']),
				is_public=bool(int(row['is_public'])),
				verified=bool(int(row['verified'])),
				members_limit=int(row['members_limit']),
				is_limited=(int(row['members_limit'])!=0)
			)
			circle.save() 

Me sale este error:
docker-compose run --rm django python manage.py shell_plus
Starting cride-platzi-1-codebase_postgres_1 … done
PostgreSQL is available
Traceback (most recent call last):
File “manage.py”, line 7, in <module>
from django.utils.six import PY3
ModuleNotFoundError: No module named ‘django.utils.six’

circles = [
    ["Facultad de Ciencias, UNAM","unam-fciencias",1,1,0],
    ["Tec de Monterrey, Campos Santa Fé","itesm-csf",1,1,0],
    ["Inventive","inventive",0,1,30],
    ["Platzi Bogotá","platzi-bog",0,1,120],
    ["Platzi México","platzi-mex",0,1,30],
    ["Google México","google-mx",0,1,250],
    ["Curso de Fotografía, UVA","curso-foto-uva",1,0,25],
    ["Equipo de futbol, chapinero","fut-chapinero",1,0,40],
    ["Grupo 3340, Prácticas de campo","grupo-3340-campo",1,0,50],
    ["Generación 2018 Escuela de enfermería","enfermeria-2018",1,0,0],
    ["Facultad de Ingeniería, UNAM","unam-fi",1,1,0],
    ["Facultad de Medicina, UNAM","unam-fm",1,1,0],
    ["Platzi Developer Circle - Bogotá","platzi-dev",1,0,0],
    ["Platzi Developer Circle - CDMX","platzi-dev-mx",1,0,0],
    ["IBM Santa Fé","ibm-santafe",0,1,0],
    ["P&G - Santa Fé","p-n-g",1,0,1000],
    ["Amigos de Centraal","comunidad-centraal",1,0,0],
    ["Central Academy","centraal-academy",1,1,0],
    ["Estado de México - CDMX","edomex",1,0,0],
    ["Satelite - Santa Fé entre semana","sat-sfe-week",1,0,0],
    ["Sable Digital","sable",0,0,30],
]

for i in circles:
	Cricle.objects.create(
	name=i[0],
 	slug_name = i[1],
  	is_public = i[2],
	verified = i[3],
	members_limit = i[4])

Recomiendo usar el comando que ofrece django-extensions para ejecutar scripts personalizados. Pueden revisar la documentación para más detalles https://django-extensions.readthedocs.io/en/latest/runscript.html

python manage.py runscript [nombre_del_script] 

Si tienen un error con la codificación del archivo csv al momento de cargalo…
UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xff in position 0: invalid start byte
Pueden hacer los siguiente:

import csv
with open('circles.csv', mode='r', encoding='utf16') as csv_file:
	csv_reader = csv.reader(csv_file)
	line = 0
	for row in csv_reader:
		if line > 0:
			circle = Circle(
				name=row[0],
				slug_name=row[1],
				is_public=int(row[2]),
				verified=int(row[3]),
				members_limit=int(row[4])
			)
			circle.save()
		line += 1	

Solución al reto:

import csv

with open('/app/circles.csv', mode='r') as f:
    for line in csv.DictReader(f):
        if int(line['members_limit']) > 0:
            line['is_limited'] = True
        else:
            line['is_limited'] = False

        c = Circle(**line)
        c.save()```
import csv

def get_data(file_name):
    rows = []
    data_file = open(file_name , 'r')
    reader = csv.reader(data_file)
    next(reader,None)
    for row in reader:
        circle = Circle(
            name=row[0],
            slug_name=row[1],
            is_public=int(row[2]),
            verified=int(row[3]),
            is_limited = False if int(row[4]) == 0 else True,
            members_limit = row[4]
        )
        circle.save()

Explica como correr un shell de Python en el docker.

Importar datos vía CSV

Les comparto mi función para importar los datos del archivo .CSV a la base de datos.

<h3>Código</h3>
import csv

 def load_data(file):
     # Open file and read its content
     with open(file, newline='') as csvfile:
         # Serialize data
         reader = csv.DictReader(csvfile)
         counter = 0
         for row in reader:
             # Store data
             instance = Circle()
             instance.name = row.get('name')
             instance.slug_name = row.get('slug_name')
             instance.is_public = bool(row.get('is_public', 0))
             instance.verified = bool(row.get('verified', 0))
             instance.members_limit = int(row.get('members_limit', 0))
             instance.is_limited = instance.members_limit > 0
             instance.save()
             counter += 1
         print(f'{counter} new rows has been inserted into the database.')

Este fue mi codigo, trate de generalizar la función para usarla con más modelos y sus csv en caso de ser necesario

import csv
from cride.circles.models import Circle

def load_data(filename, db_name):
    with open(f'{filename}.csv', encoding='utf-8') as f:
        file = csv.reader(f)
        headers = dict()
        for n,row in enumerate(file):
            if n == 0:
                headers = row
            else:
                # Create a dict with all the data
                data = dict(zip(headers, row))
                if data['members_limit'] != '0':
                    data['is_limited'] = True
                else:
                    data['is_limited'] = False
                print(data)
                # Create an instance in DB
                circle = db_name.objects.create(**data)
                # Save it
                circle.save()

        print(headers)

if __name__ == "__main__":
    load_data('circles', Circle)