我采用以下形式,其中用户选择一个与名为“持续时间”的模型中名称值的持续时间字段相对应的值。
提交表单时出现此错误
return (24 * 60 * 60 * delta.days + delta.seconds) * 1000000 + delta.microseconds
Attribute Error - 'str' object has no attribute days.
很明显,当调用此方法并获取字符串时,Django期望该参数为timedelta对象。我在哪里错?
表格:
class AuctionCreateForm(forms.ModelForm):
class Meta:
model = Auction
fields = ['title', 'reserve']
exclude = ('duration',)
labels = {'reserve': _('Reserve')}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["duration_value"] = forms.ModelChoiceField(
queryset=Duration.objects.all(),
empty_label=None,
to_field_name="value",
)
视图:
class AuctionCreate(CreateView):
""" View function for creating an auction """
form_class = AuctionCreateForm
template_name = "auction/auction_form.html"
def form_valid(self, form):
form.instance.start = timezone.now()
duration_value = form.cleaned_data.get('duration_value')
form.instance.duration = Duration.objects.get(value=duration_value)
form.instance.creator = self.request.user
return super().form_valid(form)
如果有帮助,这里有两个模型。
class Auction(models.Model):
""" Model for an auction """
uuid = models.UUIDField(
db_index=True,
default=uuid.uuid4,
editable=False,
)
title = models.CharField(max_length=10)
valid_from = models.DateTimeField(auto_now_add=True)
duration = models.ForeignKey(
Duration,
on_delete=models.SET_NULL,
null=True
)
reserve = models.PositiveIntegerField(default=0)
creator = models.ForeignKey(
get_user_model(),
on_delete=models.SET_NULL,
null=True,
)
winning_bid = models.ForeignKey(
'Bid',
related_name='highest_bid',
on_delete=models.SET_NULL,
null=True,
blank=True,
)
class Duration(models.Model):
""" Choice durations for auction """
value = models.DurationField()
def __str__(self):
return humanfriendly.format_timespan(self.value)
我知道我的持续时间对象没有任何问题。我通过管理界面成功创建了它们,该界面提供了一个文本字段,并以秒为单位输入了一个值。此外,在应用程序的另一部分中,我列出了拍卖,我可以检索这些值并对它们进行算术运算。
完整追溯-
[22/Apr/2019 13:08:54] "GET /auction/create/ HTTP/1.1" 200 3234
Internal Server Error: /auction/create/
Traceback (most recent call last):
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/views/generic/base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/views/generic/base.py", line 97, in dispatch
return handler(request, *args, **kwargs)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/views/generic/edit.py", line 172, in post
return super().post(request, *args, **kwargs)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/views/generic/edit.py", line 141, in post
if form.is_valid():
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/forms/forms.py", line 185, in is_valid
return self.is_bound and not self.errors
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/forms/forms.py", line 180, in errors
self.full_clean()
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/forms/forms.py", line 381, in full_clean
self._clean_fields()
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/forms/forms.py", line 399, in _clean_fields
value = field.clean(value)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/forms/fields.py", line 148, in clean
value = self.to_python(value)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/forms/models.py", line 1248, in to_python
value = self.queryset.get(**{key: value})
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/db/models/query.py", line 402, in get
num = len(clone)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/db/models/query.py", line 256, in __len__
self._fetch_all()
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/db/models/query.py", line 1242, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/db/models/query.py", line 55, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1084, in execute_sql
sql, params = self.as_sql()
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 486, in as_sql
where, w_params = self.compile(self.where) if self.where is not None else ("", [])
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 402, in compile
sql, params = node.as_sql(self, self.connection)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/db/models/sql/where.py", line 81, in as_sql
sql, params = compiler.compile(child)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 402, in compile
sql, params = node.as_sql(self, self.connection)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/db/models/lookups.py", line 163, in as_sql
rhs_sql, rhs_params = self.process_rhs(compiler, connection)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/db/models/lookups.py", line 260, in process_rhs
return super().process_rhs(compiler, connection)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/db/models/lookups.py", line 95, in process_rhs
return self.get_db_prep_lookup(value, connection)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/db/models/lookups.py", line 187, in get_db_prep_lookup
[get_db_prep_value(value, connection, prepared=True)]
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 1619, in get_db_prep_value
return duration_microseconds(value)
File "/home/ross/.local/share/virtualenvs/v4-MIvAvlKB/lib/python3.6/site-packages/django/utils/duration.py", line 44, in duration_microseconds
return (24 * 60 * 60 * delta.days + delta.seconds) * 1000000 + delta.microseconds
这是选择小部件的html的样子-
<select name="duration_value" id="id_duration_value">
<option value="0:05:00">5 minutes</option>
<option value="0:10:00">10 minutes</option>
<option value="0:20:00">20 minutes</option>
<option value="0:40:00">40 minutes</option>
<option value="1:00:00">1 hour</option>
<option value="2:00:00">2 hours</option>
<option value="4:00:00">4 hours</option>
<option value="8:00:00">8 hours</option>
<option value="16:00:00">16 hours</option>
<option value="1 day, 0:00:00">1 day</option>
</select>
答案 0 :(得分:0)
因此,问题是DurationField
在timedelta
对象上起作用。因此,您需要将字符串转换为timedelta
对象,然后执行查找
# views.py
from django.utils.dateparse import parse_duration
class AuctionCreate(CreateView):
""" View function for creating an auction """
form_class = AuctionCreateForm
template_name = "auction/auction_form.html"
def form_valid(self, form):
form.instance.start = timezone.now()
duration_value = form.cleaned_data.get('duration_value')
duration_obj = parse_duration(duration_value) # convert string to timedelta object
form.instance.duration = Duration.objects.get(value=duration_obj)
form.instance.creator = self.request.user
return super().form_valid(form)
答案 1 :(得分:0)
以防万一...
让它像这样在功能上起作用-
@login_required
def AuctionCreate(request):
if request.method == 'POST':
request.POST = request.POST.copy()
duration_value = request.POST["duration_value"]
duration_value = parse_duration(duration_value)
request.POST["duration_value"] = duration_value
print(request.POST)
form = AuctionCreateForm(request.POST)
if form.is_valid():
Auction.objects.create(
title=form.cleaned_data["title"],
valid_from=timezone.now(),
duration=Duration.objects.get(value=duration_value),
reserve=form.cleaned_data["reserve"],
creator=request.user,
winning_bid=None
)
return HttpResponse("Created auction")
else:
return HttpResponse("Something went wrong")
else:
form = AuctionCreateForm()
return render (
request,
'auction/auction_form.html',
{
'form': form
}
)
对于基于类的视图,就像这样-
""" View function for creating an auction """
form_class = AuctionCreateForm
template_name = "auction/auction_form.html"
def post(self, request, *args, **kwargs):
request.POST = request.POST.copy()
duration_value = request.POST["duration_value"]
duration_value = parse_duration(duration_value)
request.POST["duration_value"] = duration_value
return super().post(request, *args, **kwargs)
def form_valid(self, form):
form.instance.start = timezone.now()
duration_value = form.cleaned_data.get('duration_value')
form.instance.duration = duration_value
form.instance.creator = self.request.user
return super().form_valid(form)