2014-01-13 3 views
1

Я использую Cloud9 (который из того, что я читал, использует Python 2.6 в настоящее время, а не Python 3), чтобы написать приложение Django. Я пытаюсь прочитать CSV-файл с DictReader и использовать каждый столбец в CSV для создания нового экземпляра модели и заполнения полей модели.Проблема с чтением CSV в Django с python DictReader

views.py

class GenerateFromCSV(CreateView): 
    model = group 
    template_name = "my_app/csv_generate.html" 
    def form_valid(self, form): 
     new_group = form.save() 
     the_csv = open(new_group.group_csv, 'rbU') 
     fieldnames = ['c_type', 'f_name', 'q_type', 'ans', 'n_questions', 'bucket'] 
     data_file = csv.DictReader(the_csv, fieldnames = fieldnames, delimiter=',', dialect=csv.excel) 
     for row in data_file: 
      new_card = Card(
       name = 'card', 
       card_type = row['c_type'], 
       file_name = row['f_name'], 
       question_type = row['q_type'], 
       answer = row['ans'], 
       num_questions = row['n_questions'], 
       bucket = row['bucket'], 
       exam = new_exam) 
      new_card.save() 

models.py

class Group(models.Model): 
    name = models.CharField(max_length=255, blank = True) 
    subject = models.CharField(max_length=255, choices = SUBJECT, blank = True) 
    num_questions = models.IntegerField(default=0, blank = True, null = True) 
    group_csv = models.FileField(upload_to='csv', blank = True, null = True) 
    def __unicode__(self): 
     return self.name 

class Card(models.Model): 
    name = models.CharField(max_length=255, blank = True) 
    #ordered same as column order in CSV 
    card_type = models.CharField(max_length=255, choices = CARDTYPE, blank = True) 
    file_name = models.CharField(max_length=255, blank = True) 
    question_type = models.IntegerField(default = 0, blank = True, null = True) 
    answer = models.IntegerField(max_length = 1, choices = ANSWERS, blank = True, null = True) 
    num_questions = models.IntegerField(default = 0, blank = True, null = True) 
    bucket = models.CharField(max_length=255, blank = True) 
    exam = models.ForeignKey(Exam) 
    def __unicode__(self): 
     return self.name or 'card' 

С кодом, как это выше, я получаю TypeError (Принуждение к Unicode: нужно строка или буфер, FieldFile найден), когда Я вызываю open() в CSV. Если я удалю вызов open(), я получаю сообщение об ошибке: «символ новой строки, видимый в некотируемом поле - вам нужно открыть файл в режиме универсальной-новой строки?»

Мой CSV в формате (не каждый столбец содержит данные в каждой строке):

3,the_file_name.png,0,"00001",,Equations 

Что такое правильный синтаксис для этого?

Редактировать Вот мой StackTrace:

Traceback: 
File "/usr/libexec/openshift/cartridges/c9-0.1/root/python2.6.6/site-packages/Django-1.5-py2.6.egg/django/core/handlers/base.py" in get_response 
    115.       response = callback(request, *callback_args, **callback_kwargs) 
File "/usr/libexec/openshift/cartridges/c9-0.1/root/python2.6.6/site-packages/Django-1.5-py2.6.egg/django/views/generic/base.py" in view 
    68.    return self.dispatch(request, *args, **kwargs) 
File "/usr/libexec/openshift/cartridges/c9-0.1/root/python2.6.6/site-packages/Django-1.5-py2.6.egg/django/views/generic/base.py" in dispatch 
    86.   return handler(request, *args, **kwargs) 
File "/usr/libexec/openshift/cartridges/c9-0.1/root/python2.6.6/site-packages/Django-1.5-py2.6.egg/django/views/generic/edit.py" in post 
    199.   return super(BaseCreateView, self).post(request, *args, **kwargs) 
File "/usr/libexec/openshift/cartridges/c9-0.1/root/python2.6.6/site-packages/Django-1.5-py2.6.egg/django/views/generic/edit.py" in post 
    165.    return self.form_valid(form) 
File "/var/lib/stickshift/52a55ef4e0b8cde0ff000036/app-root/data/705411/zamrdjango/zamr/views.py" in form_valid 
    35.   with new_exam.exam_csv.open('rbU') as the_csv: 

Exception Type: AttributeError at /import/ 
Exception Value: 'NoneType' object has no attribute '__exit__' 
+0

Что такое 'new_item = Item (' вы имели в виду 'new_card = Card' вместо? –

+0

Да, я отредактировал его как правильное. – ekrah

ответ

0

Посмотрите в документации для FileField, поскольку проблема вы не передавая имя файла в файл open функции:
https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.fields.files.FieldFile

Вместо этого может быть ваш код:

class GenerateFromCSV(CreateView): 
    model = group 
    template_name = "my_app/csv_generate.html" 
    def form_valid(self, form): 
     new_group = form.save() 
     with new_group.group_csv.open('rbU') as the_csv: 
      fieldnames = ['c_type', 'f_name', 'q_type', 'ans', 'n_questions', 'bucket'] 
      data_file = csv.DictReader(the_csv, fieldnames = fieldnames, delimiter=',', dialect=csv.excel) 
      for row in data_file: 
       new_card = Card(
        name = 'item', 
        card_type = row['c_type'], 
        file_name = row['f_name'], 
        question_type = row['q_type'], 
        answer = row['ans'], 
        num_questions = row['n_questions'], 
        bucket = row['bucket'], 
        exam = new_exam) 
       new_card.save() 
+0

Понятно, что я не понял Python с/как утверждение. теперь получаю ошибку атрибута: объект «NoneType» не имеет атрибута «__exit__». Я не уверен, как справиться с этим, обработчик контекста пытается вызвать __exit__ в файле csv, но не может? – ekrah

+0

yes '__exit__' вызывается на объекте 'the_csv' в конце блока' with' ... Нечетно, что вы должны получить эту ошибку, если 'the_csv' является' None', хотя похоже, что еще одно исключение было бы поднято ранее. полная трассировка стека? – Anentropic

+0

Хорошо, я добавил трассировку выше. Я также попытался убедиться, что каждый столбец в каждой строке имеет данные, в случае возникновения проблемы, и пытается использовать другой csv (в случае, если я использовал i nvalid по какой-либо причине), но я все равно получаю ту же ошибку атрибута. – ekrah

0

Ну, я закончил тем, что исправил его, вместо того чтобы позвонить .read() на csv, а затем позвонить .splitlines(), чтобы получить строки и столбцы для каждой строки. Вот мой новый views.py:

def form_valid(self, form): 
    new_group = form.save() 
    print(new_exam.exam_csv.name) 
    data = new_group.group_csv.read() 
    rows = data.splitlines() 
    for row in rows: 
     columns = row.split(',') 
     print(columns) 
     new_card = Card(
      name = columns[0], 
      card_type = columns[0], 
      file_name = columns[1], 
      question_type = int(columns[2]), 
      answer = columns[3].replace('"', '').strip(), 
      num_questions = columns[4], 
      bucket = columns[5], 
      group = new_group) 
     print(new_card.name) 
     new_card.save() 

Я уверен, что это не правильный синтаксис или конвенция, и есть еще несколько вещей, чтобы выяснить (как имена столбцов), но сейчас это правильно разбор всю информацию в правильные поля модели.

Смежные вопросы