Объект 'tuple' не имеет атрибута 'created' при загрузке данных в формате excel в django?

views.py

def download_excel(request):
  if request.user.admin == True and request.user.admin_approval == True:
    # content-type of response
    response = HttpResponse(content_type='application/ms-excel')

    #decide file name
    response['Content-Disposition'] = 'attachment; filename=Products' + \
        str(datetime.datetime.now()) + '.xls'

    #creating workbook
    wb = xlwt.Workbook(encoding='utf-8')

    #adding sheet
    ws = wb.add_sheet("Products")

    # Sheet header, first row
    row_num = 0

    font_style = xlwt.XFStyle()
    date_style = xlwt.XFStyle()
    date_style.num_format_str = 'DD-MM-YY'

    # headers are bold
    font_style.font.bold = True

    #column header names, you can use your own headers here
    columns = ['Added Date', 'Modified Date', 'Vendor ID','Product ID','Item No','Color','Stock','Approval Status','Approved Date','Approved By', ]

    #write column headers in sheet
    for col_num in range(len(columns)):
        ws.write(row_num, col_num, columns[col_num], font_style)

    # Sheet body, remaining rows
    font_style = xlwt.XFStyle()


    rows = ProductVariants.objects.all().values_list('created','edited','vendoruser','product_id',
                                                'item_num','variant_value','initial_stock','approval_status',
                                                'approved_date','approved_by',)


    


    for my_row in rows:
        row_num = row_num + 1
        ws.write(row_num, 0, my_row.created, font_style)
        ws.write(row_num, 1, my_row.edited, font_style)
        ws.write(row_num, 2, my_row.vendoruser, font_style)
        ws.write(row_num, 3, my_row.product_id, font_style)
        ws.write(row_num, 4, my_row.item_num, font_style)
        ws.write(row_num, 5, my_row.variant_value, font_style)
        ws.write(row_num, 6, my_row.initial_stock, font_style)
        ws.write(row_num, 7, my_row.approval_status, font_style)
        ws.write(row_num, 8, my_row.approved_date, font_style)
        ws.write(row_num, 9, my_row.approved_by, font_style)
        
        wb.save(response)
        return response

Я использовал это, и это работает, но я не получаю значения внешнего ключа, вместо этого я получаю id поля внешнего ключа. Поэтому я использовал приведенный выше код, но это дает ошибку 'tuple' object has no attribute 'created'. Я хочу получить значения для соответствующих столбцов. Пожалуйста, мне нужно решение этой проблемы

   for row in rows:
       row_num +=  1                
      
      for col_num in range(len(row)):
              ws.write(row_num, col_num,str(row[col_num]), font_style)

values_list выдает список кортежей со значениями полей, перечисленных в качестве аргументов в каждом кортеже. Вы не можете вызвать эти значения так my_row.created, потому что каждое значение в кортеже имеет только индекс, поэтому вы можете вызвать их только по индексу my_row[0], my_row[1]...

Вы можете использовать values вместо values_list, тогда вы получите список dicts, в котором вы можете вызывать каждое значение по ключу.

rows = ProductVariants.objects.all().values(
    'created','edited','vendoruser','product_id',
    'item_num','variant_value','initial_stock',
    'approval_status','approved_date','approved_by',
)
for my_row in rows:
    row_num = row_num + 1
    ws.write(row_num, 0, my_row['created'], font_style)
    ...

Кроме того, в методе .values_list() можно определить и поля foreign_key! Например, если approved_by является пользователем и имеет поле name:

ProductVariants.objects.all().values_list('created','edited', 'approved_by__name')

Укажите двойное подчеркивание между foreign_key и полем модели.


Но ошибка говорит о другом:

for my_row in rows:
    row_num = row_num + 1
        ...

my_row - это объект кортежа. Поэтому вам нужно сначала распаковать его:

for my_row in rows:
    print(my_row)
    created, edited, ...add_more_values_here = myrow
    row_num = row_num + 1
    ws.write(row_num, 0, created, font_style)
    ...
Вернуться на верх