返回顶部

Django系统报错总结 1

Django系统报错总结 1

  本章节,继续总结前面商品系统编写中遇到的报错问题

TypeError: Product() got unexpected keyword arguments: 'update_time', 'seller'

因为在Product类中没有定义参数update_time和seller。要解决这个问题,你需要确保在Product类中添加这些参数的定义。

## 定义的创建一个新的商品实例
new_product = Product(
    name=name,
    price=price,
    description=description,
    created_time=created_time,
    update_time=update_time,
    photo=photo,
    video=video,
    seller=request.user
)

#因为在Product()构造函数中有未预期的关键字参数'update_time''seller'。解决方法是检查Product类的构造函数,确保它接受这些参数。如果没有,可以添加相应的参数来修复这个错误
from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=200)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    description = models.TextField()
    created_time = models.DateField(auto_now_add=True)
    updated_time = models.DateTimeField(auto_now=True)
    photo = models.ImageField(upload_to='product_photos/', blank=True)
    video = models.FileField(upload_to='product_videos/', blank=True)

    def __str__(self):
        return self.name

# 在创建Product对象时指定seller和update_time
def add_product(request):
    ...
    创建一个新的商品实例
        new_product = Product(
            name=name,
            price=price,
            description=description,
            created_time=created_time,
            photo=photo,
            video=video,
        )

        new_product.seller = request.user
        new_product.updated_time = datetime.now()
        form = ProductForm(request.POST, request.FILES, instance=new_product)

报错decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]

这个错误是由于Decimal构造函数的参数不是一个有效的数字表示引起的。为了解决这个错误,需要确保传递给Decimal构造函数的参数是一个有效的数字字符串或数字类型。

在这段更新后的代码中,我们从“decimal”模块导入了“InvalidOperation”异常,并在“except”块中使用它。这可确保在转换为Decimal失败时正确捕获和处理异常。

try:
    price = Decimal(price)
    logger.info('用户%s输入价格%s为数字' % (request.user.username, price))
    messages.info(request, '价格设置成功')
except ValueError:
    messages.error(request, '价格必须为数字!')
    logger.error('用户%s尝试添加价格非数字商品' % request.user.username)
    return redirect('add_product')

#修改为
from decimal import Decimal, InvalidOperation

try:
    price = Decimal(price)
    logger.info('用户%s输入价格%s为数字' % (request.user.username, price))
    messages.info(request, '价格设置成功')
except InvalidOperation:
    messages.error(request, '价格必须为数字!')
    logger.error('用户%s尝试添加价格非数字商品' % request.user.username)
    return redirect('add_product')

init TypeError: init() got an unexpected keyword argument 'instance'

 确保在导入表单时正确导入。您可以尝试使用而不是。然后,删除参数,因为默认会处理模型实例

#报错代码
form = ProductForm(request.POST, request.FILES, instance=new_product)

#解决如下
from django import forms
from .models import Product

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = '__all__'

#使用ProductForm不带instance参数来实例化表单
form = ProductForm(request.POST, request.FILES)

form.save() AttributeError: 'ProductForm' object has no attribute 'save'

form.save() AttributeError: 'ProductForm' object has no attribute 'save'这个错误通常是因为表单对象没有定义 save() 方法。您可以检查以下内容:

  1. 确保您的表单类继承自 forms.ModelForm forms.Form
  2. 确保您在表单类中定义了 save() 方法。

ProductForm 继承自 forms.ModelForm,并定义了一个简单的 save() 方法,该方法将创建一个新的 Product 对象并保存它。

from django import forms
from .models import Product

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = ['name', 'description', 'price']

    def save(self, commit=True):
        product = super(ProductForm, self).save(commit=False)
        if commit:
            product.save()
        return product

AttributeError: 'super' object has no attribute 'save'

product = super(ProductForm, self).save(commit=False)

AttributeError: 'super' object has no attribute 'save'

这个错误通常是由于调用 super() 函数时未正确指定父类。您可以检查以下内容:

  1. 确保您的表单类继承自 forms.ModelForm forms.Form
  2. 确保您在表单类中正确地调用了 super() 函数。

ProductForm 继承自 forms.ModelForm,并定义了一个简单的 save() 方法,该方法将创建一个新的 Product 对象并保存它

from django import forms
from .models import Product

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = ['name', 'description', 'price']

    def save(self, commit=True):
        product = super(ProductForm, self).save(commit=False)
        if commit:
            product.save()
        return product

ValueError: MultiFileInput doesn't support uploading multiple files.

报错代码如下: ValueError: MultiFileInput doesn't support uploading multiple files.

from django import forms
from .models import Product

class MultiFileInput(forms.FileInput):
    def __init__(self, attrs=None):
        super().__init__(attrs={'multiple': True, **(attrs or {})})

    def render(self, name, value, attrs=None, renderer=None):
        if value is None:
            value = []
        final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
        if value != []:
            final_attrs.update({'multiple': 'multiple'})

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = '__all__'
        widgets = {
            'photo': MultiFileInput(),
            'video': MultiFileInput(),
        }

这个错误可能是因为您的Django版本不支持在render()方法中使用multiple属性。可以将multiple属性添加到self.attrs中,而不是在render()方法中添加。

将multiple属性添加到了小部件的初始化方法中。然后,在表单的__init__()方法中,我们将multiple属性添加到了小部件的属性中,以便在渲染表单时正确显示多个文件上传控件。

from django import forms
from .models import Product

class MultiFileInput(forms.FileInput):
    def __init__(self, attrs=None):
        super().__init__(attrs={'multiple': True, **(attrs or {})})

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = '__all__'
        widgets = {
            'photo': MultiFileInput(),
            'video': MultiFileInput(),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['photo'].widget.attrs.update({'multiple': 'multiple'})
        self.fields['video'].widget.attrs.update({'multiple': 'multiple'})

django-multiupload库解决

上述方法若还是报错,可使用第三方库
可能是因为您使用的Django版本不支持在render()方法中使用multiple属性。为了解决这个问题,您可以尝试使用一个第三方库,例如django-multiupload,它提供了对多文件上传的支持。
使用django-multiupload库的示例:
使用了MultiFileField来替代原来的照片和视频字段。您可以根据实际需求设置最小和最大文件数量以及最大文件大小。
请注意,使用第三方库可能会导致一些额外的配置和调整。请参考django-multiupload的文档以获取更多详细信息和用法示例。

安装django-multiupload库:

 pip install django-multiupload
 

settings.py文件中添加multiupload到INSTALLED_APPS:

INSTALLED_APPS = [
# ...
'multiupload',
]

表单中使用MultiFileField

from django import forms
from multiupload.fields import MultiFileField
from .models import Product

class ProductForm(forms.ModelForm):
    photos = MultiFileField(min_num=1, max_num=10, max_file_size=1024*1024*5)  # 设置最小和最大文件数量以及最大文件大小

    class Meta:
        model = Product
        fields = '__all__'

TypeError: __init__() missing 1 required positional argument: 'to'

photo = models.ManyToManyField(upload_to='product_photos/', blank=True)
TypeError: __init__() missing 1 required positional argument: 'to'
这个错误是由于ManyToManyField的to参数缺失导致的。你需要在ManyToManyField中指定关联的模型类作为to参数的值。
解决方法是在ManyToManyField的to参数中提供关联的模型类。例如,如果关联的模型类名为Product,则可以将to参数设置为to='Product'

 
photo = models.ManyToManyField(upload_to='product_photos/', blank=True)

#修改为
photo = models.ManyToManyField('Product', upload_to='product_photos/', blank=True)

报错个人总结

  上面仅仅只是一部分报错,在编写功能的时候出现的状况问题更多,在这里总结几点我认为有效的建议。

1、先确定构思所需要的功能,大概的框架先想好构思

2、编写注释,在将构思落实之前先写好注释,再在每个功能里面写好注释怎么去完成这个功能

3、一个功能完成,立即去测试验证能否实现要求的场景功能

4、不要钻牛角尖,在这个问题实在解决不了的情况,可以换个思路去解决,等完全实现了在去研究之前的问题出现在哪。不能一直卡在一个问题

 5、很多时候报错有以下几点导致的: 
  •   新写的代码语法或逻辑有问题
  •   没有导入所引入的模块
  •   代码多出或缺少字符
  •   模版中引用代码的参数不匹配

6、对于代码的功能优化和页面优化,可以本着先实现,再优化。可以通过Google,GPT帮我们锦上添花。

 

posted @ 2023-09-02 10:43  九尾cat  阅读(242)  评论(0编辑  收藏  举报