У объекта 'NoneType' нет атрибута '__getitem__' Django, я застрял при попытке следовать учебнику - PullRequest
0 голосов
/ 20 июня 2019

Привет всем, я студент из Индонезии, Я слежу за видео-уроком о том, как сделать веб-сайт специально для цифрового рынка, так что есть часть, когда я пытаюсь сделать функцию «автоматически сгенерированных миниатюр» из картинки с высоким разрешением, которую мы загружаем, но в итоге я получил такую ​​ошибку , что заставило меня застрять в моем проекте

сначала я использую django версии 1.8.6 и python ver 2.7.10

вот мои модели.py

from django.conf import settings
from django.core.urlresolvers import reverse

from django.db import models
from django.db.models.signals import pre_save, post_save #signal
from django.utils.text import slugify #signal
from django.core.files.storage import FileSystemStorage

def download_media_location(instance, filename):
    return "%s/%s" %(instance.slug,filename)

class Produk(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    managers = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="managers_produk", blank=True)
    media = models.ImageField(
            blank=True,
            null=True,
            upload_to=download_media_location,
            storage=FileSystemStorage(location=settings.PROTECTED_ROOT)#memindahkan dr media ke protected
            )
    judul = models.CharField(max_length=30)
    slug = models.SlugField(blank=True, unique=True)
    deskripsi = models.TextField()
    harga = models.DecimalField(max_digits=100, decimal_places=2, default=1000.0)
    harga_sale = models.DecimalField(max_digits=100, decimal_places=2, default=1000.0, null=True, blank=True) #bisa di kosongin

    def __unicode__(self):#menampilkan list di admin berdasarkan judul
        return self.judul



    def get_absolute_url(self):#absolute url redirect success url ke slug path
        view_name = "produk:detail_slug"
        return reverse(view_name, kwargs={"slug":self.slug})


    def get_download(self):
        view_name = "produk:download_slug"
        url = reverse(view_name, kwargs={"slug":self.slug})
        return url


def create_slug(instance, new_slug=None):
        slug = slugify(instance.judul)
        if new_slug is not None:
                slug=new_slug
        qs = Produk.objects.filter(slug=slug)
        exists = qs.exists()
        if exists:
                new_slug = "%s-%s" %(slug, qs.first().id)
                return create_slug(instance,new_slug=new_slug)
        return slug

def produk_pre_save_receiver(sender,instance,*args,**kwargs):
    if not instance.slug:
        instance.slug = create_slug(instance) #otomatis buat slug sebelum save pakai signal

pre_save.connect(produk_pre_save_receiver,sender=Produk)




##################################THUMBNAIL MODEL 2nd PART##############


def thumbnail_location(instance, filename):
    return "%s/%s" %(instance.produk.slug, filename)

THUMB_CHOICES = (
    ("hd", "HD"),
    ("sd", "SD"),
    ("micro", "Micro"),
)

class Thumbnail(models.Model):
    produk = models.ForeignKey(Produk)
    #user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True,blank=True)
    type = models.CharField(max_length=20, choices=THUMB_CHOICES, default='hd')
    height = models.CharField(max_length=20, null=True, blank=True)
    width = models.CharField(max_length=20, null=True, blank=True)
    media = models.ImageField(
            width_field = "width",
            height_field = "height",
            blank=True,
            null=True,
            upload_to=thumbnail_location
            )

    def __unicode__(self):
        return str(self.media.path)

import os
import shutil
from PIL import Image
import random

from django.core.files import File

def produk_post_save_receiver(sender,instance,created,*args,**kwargs):
    if instance.media:
        hd = Thumbnail.objects.get_or_create(produk=instance, type='hd')[0]
        sd = Thumbnail.objects.get_or_create(produk=instance, type='sd')[0]
        micro = Thumbnail.objects.get_or_create(produk=instance, type='micro')[0]

        hd_max = (400, 400)
        sd_max = (200, 200)
        micro_max = (50, 50)

        print instance.media.path
        filename = os.path.basename(instance.media.path)
        print filename
        thumb = Image.open(instance.media.path)
        thumb.thumbnail(hd_max, Image.ANTIALIAS)
        temp_loc = "%s\%s\smt" %(settings.MEDIA_ROOT, instance.slug)
        print temp_loc

        if not os.path.exists(temp_loc):
            os.makedirs(temp_loc)

        temp_file_path = os.path.join(temp_loc, filename)
        print temp_file_path
        if os.path.exists(temp_file_path):
            temp_path = os.path.join(temp_loc, "%s" %(random.random()))
            os.makedirs(temp_path)
            temp_file_path = os.path.join(temp_path, filename)

        temp_image = open(temp_file_path, "w")   
        thumb.save(temp_image) 
        thumb_data = open(temp_file_path, "r")
        thumb_file = File(thumb_data)
        hd.media.save(filename, thumb_file)
        #shutil.rmtree(temp_loc, ignore_errors=True)

post_save.connect(produk_post_save_receiver, sender=Produk)

class MyProduk(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL) #satu user hanya 1 set produk
    produk = models.ManyToManyField(Produk, blank=True)

    def __unicode__(self):
        return "%s" %(self.produk.count())

    class Meta:
        verbose_name = "My Produk"
        verbose_name_plural = "My Produk"

вот и весь код models.py,

Я собираюсь объяснить, что там произошло, поэтому я создаю модель Produk, которая содержит несколько полей (например, Название, цена и т. Д.), Одно из них - ImageField, я создаю автоматически сгенерированные слагы и так далее,

утверждая, что во 2-й части (которую я там их пометил) я создал модель миниатюр, я комбинирую две модели, используя Tabular Inline в моем admin.py,

я использую сигнал для создания автоматически созданного эскиза с помощью produk_post_save_receiver, который будет срабатывать после нажатия пользователем кнопки сохранения,

Я запускаю сервер и захожу на мой локальный сервер / администратор. Все выглядит нормально, но когда я пытаюсь добавить продукт, добавить изображение и сохранить его, я получаю сообщение об ошибке, это вся ошибка

TypeError at /admin/produk/produk/add/
'NoneType' object has no attribute '__getitem__'
Request Method: POST
Request URL:    http://127.0.0.1:8000/admin/produk/produk/add/
Django Version: 1.8.6
Exception Type: TypeError
Exception Value:    
'NoneType' object has no attribute '__getitem__'
Exception Location: C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\core\files\images.py in _get_width, line 17
Python Executable:  C:\Users\Papamegumi\Desktop\Skripsiv2\Scripts\python.exe
Python Version: 2.7.10
Python Path:    
['C:\\Users\\Papamegumi\\Desktop\\Skripsiv2\\src',
 'C:\\Windows\\SYSTEM32\\python27.zip',
 'C:\\Users\\Papamegumi\\Desktop\\Skripsiv2\\DLLs',
 'C:\\Users\\Papamegumi\\Desktop\\Skripsiv2\\lib',
 'C:\\Users\\Papamegumi\\Desktop\\Skripsiv2\\lib\\plat-win',
 'C:\\Users\\Papamegumi\\Desktop\\Skripsiv2\\lib\\lib-tk',
 'C:\\Users\\Papamegumi\\Desktop\\Skripsiv2\\Scripts',
 'c:\\python27\\Lib',
 'c:\\python27\\DLLs',
 'c:\\python27\\Lib\\lib-tk',
 'C:\\Users\\Papamegumi\\Desktop\\Skripsiv2',
 'C:\\Users\\Papamegumi\\Desktop\\Skripsiv2\\lib\\site-packages']
Server time:    Fri, 21 Jun 2019 00:21:50 +0700

весь трассировщик здесь:

Traceback Switch to copy-and-paste view
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\core\handlers\base.py in get_response
                                response = wrapped_callback(request, *callback_args, **callback_kwargs) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\contrib\admin\options.py in wrapper
                            return self.admin_site.admin_view(view)(*args, **kwargs) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\utils\decorators.py in _wrapped_view
                                response = view_func(request, *args, **kwargs) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\views\decorators\cache.py in _wrapped_view_func
                    response = view_func(request, *args, **kwargs) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\contrib\admin\sites.py in inner
                        return view(request, *args, **kwargs) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\contrib\admin\options.py in add_view
                    return self.changeform_view(request, None, form_url, extra_context) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\utils\decorators.py in _wrapper
                        return bound_func(*args, **kwargs) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\utils\decorators.py in _wrapped_view
                                response = view_func(request, *args, **kwargs) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\utils\decorators.py in bound_func
                            return func.__get__(self, type(self))(*args2, **kwargs2) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\utils\decorators.py in inner
                                return func(*args, **kwargs) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\contrib\admin\options.py in changeform_view
                            self.save_model(request, new_object, form, not add) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\contrib\admin\options.py in save_model
                    obj.save() ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\db\models\base.py in save
                                   force_update=force_update, update_fields=update_fields) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\db\models\base.py in save_base
                                               update_fields=update_fields, raw=raw, using=using) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\dispatch\dispatcher.py in send
                        response = receiver(signal=self, sender=sender, **named) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\src\produk\models.py in produk_post_save_receiver
                    hd.media.save(filename, thumb_file) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\db\models\fields\files.py in save
                    setattr(self.instance, self.field.name, self.name) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\db\models\fields\files.py in __set__
                        self.field.update_dimension_fields(instance, force=True) ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\db\models\fields\files.py in update_dimension_fields
                        width = file.width ...
▶ Local vars
C:\Users\Papamegumi\Desktop\Skripsiv2\lib\site-packages\django\core\files\images.py in _get_width
                    return self._get_image_dimensions()[0] ...
▶ Local vars

Прошло 3 дня с тех пор, как я пытался найти решение, но получил только несколько подсказок, вот подсказки:

1. errors gone if i commented/ remove the hd.media.save(filename, thumb_file) on produk_post_save_receiver function,
2.   def __unicode__(self):
        return str(self.media.path) , this line code seems trigger another error like media has no attribute associate,

3. everything is normal when i try to make each produk or thumbnail on separate ways,

мне так неприятно знать, что именно произошло, потому что, если я посмотрю учебники, все будет в порядке,

Примечание: я использую Windows, а учебник - Mac,

Большое спасибо за ответ, очень признателен, надеюсь, кто-то, кто здесь эксперт, поможет мне. спасибо, прежде чем

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...