Django 模型表单外键字段到持续时间字段不工作
我有以下表单,其中用户选择一个值,该值对应于名为duration的模型中name值的duration字段 当表单提交时,我收到了这个错误Django 模型表单外键字段到持续时间字段不工作,django,Django,我有以下表单,其中用户选择一个值,该值对应于名为duration的模型中name值的duration字段 当表单提交时,我收到了这个错误 return (24 * 60 * 60 * delta.days + delta.seconds) * 1000000 + delta.microseconds Attribute Error - 'str' object has no attribute days. 显然,Django在调用此方法时希望参数是timedelta对象,而不是获取字符串。我
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
这是select小部件的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>
5分钟
10分钟
20分钟
40分钟
1小时
2小时
4小时
8小时
16小时
一天
因此,问题是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)
如果它能帮助任何人 函数的工作方式是这样的-
@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)
你能分享整个回溯吗?
delta
的定义是什么?我将更新问题,以了解它从数据库中提取的选择选项。如问题中所述,它们都是通过管理界面中的文本输入字段创建的-我为每个字段输入了一个整数秒值。这不起作用,因为问题发生在表单声明有效之前。我尝试过用您建议的方法覆盖post方法并将字段更改为timedelta对象,但显然您无法更改post dict,因为它是不可变的。此外,所有这些当然都是不必要的。Django应该已经注意到这一点并进行转换。