Tôi đang cố nhập tệp CSV, sử dụng biểu mẫu để tải tệp lên từ hệ thống khách. Sau khi tôi có tệp, tôi sẽ lấy một phần của nó và điền vào một mô hình trong ứng dụng của tôi. Tuy nhiên, tôi nhận được một "iterator nên trả lại chuỗi, không byte" lỗi khi tôi đi để lặp qua các dòng trong tập tin tải lên. Tôi đã dành hàng giờ cố gắng những thứ khác nhau và đọc tất cả mọi thứ tôi có thể tìm thấy trên này nhưng dường như không thể giải quyết nó (lưu ý, tôi là tương đối mới để Django-chạy 1,5 và python - chạy 3,3). Tôi đã loại bỏ mọi thứ để có được chỉ là lỗi và chạy nó như thế này để đảm bảo nó vẫn còn đó. Các lỗi được hiển thị khi thực hiện dòng "cho các câu lạc bộ trong club_list" trong tools_clubs_import():Cách giải quyết "trình vòng lặp phải trả lại chuỗi chứ không phải byte"
Sau đây là views.py chỉnh mà làm việc, dựa trên câu trả lời được đánh dấu dưới đây:
import csv
from io import TextIOWrapper
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from rank.forms import ClubImportForm
def tools_clubs_import(request):
if request.method == 'POST':
form = ClubImportForm(request.POST, request.FILES)
if form.is_valid():
# the following 4 lines dumps request.META to a local file
# I saw a lot of questions about this so thought I'd post it too
log = open("/home/joel/meta.txt", "w")
for k, v in request.META.items():
print ("%s: %s\n" % (k, request.META[k]), file=log)
log.close()
# I found I didn't need errors='replace', your mileage may vary
f = TextIOWrapper(request.FILES['filename'].file,
encoding='ASCII')
club_list = csv.DictReader(f)
for club in club_list:
# do something with each club dictionary entry
pass
return HttpResponseRedirect(reverse('rank.views.tools_clubs_import_show'))
else:
form = ClubImportForm()
context = {'form': form, 'active_menu_item': 4,}
return render(request, 'rank/tools_clubs_import.html', context)
def tools_clubs_import_show(request):
return render(request, 'rank/tools_clubs_import_show.html')
Các sau đây là phiên bản gốc của những gì tôi trình (html mà tạo ra các hình thức được bao gồm ở dưới cùng của danh sách mã này: Giá trị
views.py
--------
import csv
from django.shortcuts import render
from django.http import HttpResponseRedirect
from rank.forms import ClubImportForm
def tools(request):
context = {'active_menu_item': 4,}
return render(request, 'rank/tools.html', context)
def tools_clubs(request):
context = {'active_menu_item': 4,}
return render(request, 'rank/tools_clubs.html', context)
def tools_clubs_import(request):
if request.method == 'POST':
form = ClubImportForm(request.POST, request.FILES)
if form.is_valid():
f = request.FILES['filename']
club_list = csv.DictReader(f)
for club in club_list:
# error occurs before anything here is executed
# process here... not included for brevity
return HttpResponseRedirect(reverse('rank.views.tools_clubs_import_show'))
else:
form = ClubImportForm()
context = {'form': form, 'active_menu_item': 4,}
return render(request, 'rank/tools_clubs_import.html', context)
def tools_clubs_import_show(request):
return render(request, 'rank/tools_clubs_import_show.html')
forms.py
--------
from django import forms
class ClubImportForm(forms.Form):
filename = forms.FileField(label='Select a CSV to import:',)
urls.py
-------
from django.conf.urls import patterns, url
from rank import views
urlpatterns = patterns('',
url(r'^tools/$', views.tools, name='rank-tools'),
url(r'^tools/clubs/$', views.tools_clubs, name='rank-tools_clubs'),
url(r'^tools/clubs/import$',
views.tools_clubs_import,
name='rank-tools_clubs_import'),
url(r'^tools/clubs/import/show$',
views.tools_clubs_import_show,
name='rank-tools_clubs_import_show'),
)
tools_clubs_import.html
-----------------------
{% extends "rank/base.html" %}
{% block title %}Tools/Club/Import{% endblock %}
{% block center_col %}
<form enctype="multipart/form-data" method="post" action="{% url 'rank-tools_clubs_import' %}">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
{% endblock %}
Ngoại lệ:
iterator nên trả lại chuỗi, không byte
Vị trí ngoại lệ (bạn đã mở tập tin trong chế độ văn bản?): /usr/lib/python3.3/csv.py trong fieldnames, dòng 96
Đó tạo ra "đối tượng 'InMemoryUploadedFile' không có thuộc tính 'đọc'". – MeaOrdo
@MeaOrdo: Đã cập nhật; xin lỗi, tôi không có một Django-on-3.x chạy atm, do đó, nó mã nguồn đọc và ngoại suy chỉ ở đây.:-) –
Tôi đã thử một số biến thể về mã hóa với TextIOWrapper và sử dụng StringIO thay vì TextIOWrapper. Các mã hóa khác nhau trên TextIOWrapper cho phép Không thể giải mã tại lỗi byte 10 và tất cả các biến thể sử dụng StringIO cho TypeErrors và một số kết hợp tham chiếu đến "InMemoryUploadedFile". Có phải lỗi thực sự ở giai đoạn request.FILES ['filename']? Việc chuyển cho csv.DictReader không tạo ra lỗi cho đến khi bạn cố lặp lại kết quả. – MeaOrdo