"Django Admin: AttributeError: 'list' object has no attribute 'strip' при использовании rangefilter для фильтрации по диапазону дат"
Я столкнулся с ошибкой AttributeError: 'list' object has no attribute 'strip' при попытке отфильтровать мою модель EmployeeWorkLog по диапазону дат в Django Admin, используя rangefilter. Вот мой код:
admin.py:
from django.contrib import admin
from import_export import resources
from import_export.admin import ImportExportModelAdmin
from rangefilter.filters import DateRangeFilter
from .models import EmployeeWorkLog
class EmployeeWorkLogResource(resources.ModelResource):
""" Ресурс для экспорта данных EmployeeWorkLog """
class Meta:
model = EmployeeWorkLog
fields = ('employee__name', 'order__assignment_number', 'operation__operation__name', 'date', 'quantity', 'piece_rate', 'total_cost')
export_order = fields
# Имена полей в экспортированном файле (русский)
field_names = {
'employee__name': 'Сотрудник',
'order__assignment_number': 'Заказ',
'operation__operation__name': 'Операция',
'date': 'Дата',
'quantity': 'Количество',
'piece_rate': 'Ставка за единицу',
'total_cost': 'Общая стоимость',
}
def dehydrate_date(self, obj):
return obj.date.strftime('%d-%m-%Y') if obj.date else None
@admin.register(EmployeeWorkLog)
class EmployeeWorkLogAdmin(ImportExportModelAdmin):
resource_class = EmployeeWorkLogResource
list_display = ('employee', 'order', 'operation', 'date', 'quantity', 'piece_rate', 'total_cost')
list_filter = ('employee', 'order', 'operation', ('date', DateRangeFilter),)
search_fields = ('employee__name', 'order__assignment_number', 'operation__operation__name')
readonly_fields = ('total_cost',)
date_hierarchy = 'date'
fieldsets = (
(None, {'fields': ('employee', 'order', 'operation', 'date', 'quantity', 'piece_rate')}),
('Рассчитанные данные', {'fields': ('total_cost',)}),
)
def get_readonly_fields(self, request, obj=None):
if obj:
return [field.name for field in self.model._meta.fields]
return []
models.py
from django.db import models
class Sewing(models.Model):
name = models.CharField("ФИО сотрудника", max_length=255)
class Meta:
verbose_name = "Сотрудник"
verbose_name_plural = "Сотрудники"
def __str__(self):
return self.name
class Assignment(models.Model):
assignment_number = models.CharField("Номер задания", max_length=255)
def __str__(self):
return self.assignment_number
class Operation(models.Model):
name = models.CharField("Операция", max_length=255)
class Meta:
verbose_name = "Операция"
verbose_name_plural = "Операции"
def __str__(self):
return self.name
class TechnologicalMapOperation(models.Model):
operation = models.ForeignKey(Operation, on_delete=models.CASCADE, verbose_name="Операция")
class Meta:
verbose_name = 'Операция в тех.карте'
verbose_name_plural = 'Операции в тех.карте'
def __str__(self):
return f'{self.operation.name}'
class EmployeeWorkLog(models.Model):
employee = models.ForeignKey(Sewing, on_delete=models.CASCADE, verbose_name="Сотрудник", null=True)
order = models.ForeignKey(Assignment, on_delete=models.CASCADE, verbose_name="Заказ")
operation = models.ForeignKey(TechnologicalMapOperation, on_delete=models.CASCADE, verbose_name="Операция",null=True)
date = models.DateField("Дата выполнения",)
quantity = models.PositiveIntegerField("Количество") #
piece_rate = models.DecimalField("Ставка за единицу", max_digits=8, decimal_places=2) # брать из TechnologicalMapOperation, если ставка фиксирована
total_cost = models.DecimalField("Общая стоимость", max_digits=10, decimal_places=2, editable=False)
class Meta:
verbose_name = "Журнал работ сотрудника"
verbose_name_plural = "Журналы работ сотрудников"
ordering = ['-date', 'employee']
def __str__(self):
return f"{self.employee} - {self.order} - {self.operation} - {self.date}"
def save(self, *args, **kwargs):
self.total_cost = self.quantity * self.piece_rate # Автоматический расчет общей стоимости
super().save(*args, **kwargs)
Трассировка ошибки (Traceback):
Internal Server Error: /admin/manufactory/employeeworklog/
Traceback (most recent call last):
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\contrib\admin\options.py", line 718, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\utils\decorators.py", line 188, in _view_wrapper
result = _process_exception(request, e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\utils\decorators.py", line 186, in _view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\views\decorators\cache.py", line 80, in _view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\contrib\admin\sites.py", line 241, in inner
return view(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\import_export\admin.py", line 553, in changelist_view
return super().changelist_view(request, extra_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\import_export\admin.py", line 779, in changelist_view
return super().changelist_view(request, extra_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\import_export\admin.py", line 65, in changelist_view
return super().changelist_view(request, extra_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\utils\decorators.py", line 48, in _wrapper
return bound_method(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\utils\decorators.py", line 188, in _view_wrapper
result = _process_exception(request, e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\utils\decorators.py", line 186, in _view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\contrib\admin\options.py", line 2001, in changelist_view
cl = self.get_changelist_instance(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\contrib\admin\options.py", line 866, in get_changelist_instance
return ChangeList(
^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\contrib\admin\views\main.py", line 145, in __init__
self.queryset = self.get_queryset(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\contrib\admin\views\main.py", line 553, in get_queryset
new_qs = filter_spec.queryset(request, qs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\rangefilter\filters.py", line 147, in queryset
if self.form.is_valid():
^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\forms\forms.py", line 197, in is_valid
return self.is_bound and not self.errors
^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\forms\forms.py", line 192, in errors
self.full_clean()
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\forms\forms.py", line 325, in full_clean
self._clean_fields()
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\forms\forms.py", line 333, in _clean_fields
self.cleaned_data[name] = field._clean_bound_field(bf)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\forms\fields.py", line 266, in _clean_bound_field
return self.clean(value)
^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\forms\fields.py", line 204, in clean
value = self.to_python(value)
^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\forms\fields.py", line 493, in to_python
return super().to_python(value)
^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ulukm\Documents\projects\ERP_Textile\venv\Lib\site-packages\django\forms\fields.py", line 462, in to_python
value = value.strip()
^^^^^^^^^^^
AttributeError: 'list' object has no attribute 'strip'
[25/Jan/2025 17:55:36] "GET /admin/manufactory/employeeworklog/?date__range__gte=01.11.2024&date__range__lte=30.11.2024&q= HTTP/1.1" 500 197299