In my django app I have simple Category and Offer models:
(在我的django应用中,我有简单的Category和Offer模型:)
class Category(BaseModel):
title = models.CharField(_('Category title'), max_length=256)
available = models.BooleanField(_('Is available'), default=True)
slug = models.SlugField(max_length=256, null=True, blank=True, unique=True, verbose_name=_(Slug'))
requires_item_price = models.BooleanField(default=False, verbose_name=_('Requires item price to be provided'))
class Offer(BaseModel):
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True, verbose_name=_('Category'))
item_price = models.DecimalField(max_digits=8, decimal_places=2, null=True, verbose_name=_('Item price'),
blank=True)
def clean(self):
if self.category.requires_item_price and not self.item_price:
raise ValidationError({'item_price': _('If category requires item price - you have to provide it')})
My form class:
(我的形式课:)
class NewPaginatedOfferForm(forms.ModelForm):
class Meta:
model = Offer
fields = ('item_price',)
def __init__(self, category, *args, **kwargs):
super().__init__(*args, **kwargs)
self.category = category
self.helper = FormHelper()
self.helper.form_id = self.__class__.__name__.lower()
self.initial['category'] = category
self.helper.layout = Layout(
Field('item_price'),
Div(
Submit('submit', _(Save →'),
css_class="btn btn-lg bold btn-block btn-success", ),
)
)
and my view class, based on generic CreateView class:
(和我的视图类,基于通用的CreateView类:)
class NewOfferForCategoryView(CreateView):
model = Offer
category = None
template_name = 'web/new_offer_for_category.html'
def get_form_class(self):
print('get_form_class')
if self.category.requires_item_price:
return NewPaginatedOfferForm
def get_form_kwargs(self):
print('get_form_kwargs')
kwargs = super().get_form_kwargs()
kwargs['category'] = self.category
print('kwargs:', kwargs)
return kwargs
def dispatch(self, request, *args, **kwargs):
print('dispatch, ', request.method)
try:
self.category = Category.objects.get(slug=self.kwargs.get('cat_slug'), available=True)
except:
print('wrong category')
return redirect(reverse('web:new_offer'))
print('self category is', self.category)
return super().dispatch(request, *args, **kwargs)
def form_valid(self, form):
print('form_valid')
form.instance.category = self.category
return super().form_valid(form)
def form_invalid(self, form):
print('form_invalid')
form.instance.category = self.category
return super().form_invalid(form)
def get_context_data(self, **kwargs):
print('get_context_data')
ctx = super().get_context_data(**kwargs)
ctx['categories'] = Category.objects.filter(available=True)
ctx['category'] = self.category
return ctx
GET requests are working fine.
(GET请求工作正常。)
Problem is when I try to submit such form. (问题是当我尝试提交此类表格时。)
I am always getting an error: (我总是遇到错误:)
AttributeError at /new-offer/my-category-slug
'NoneType' object has no attribute 'requires_item_price'
Request Method: POST
Request URL: http://127.0.0.1:8000/new-offer/my-category-slug
Django Version: 2.2.6
Exception Type: AttributeError
Exception Value:
'NoneType' object has no attribute 'requires_item_price'
Exception Location: /Users/User/project/core/models.py in clean, line 272
Looks like category property is None in Offer model clean method - but I am not sure why and how can I pass it there.
(看起来在Offer模型清除方法中category属性为None,但是我不确定为什么以及如何将其传递给它。)
I want to use model clean method as it covers also django's admin panel validation when new object is created there. (我想使用模型清理方法,因为当在其中创建新对象时,它也涵盖了django的管理面板验证。)
Any ideas? (有任何想法吗?)
ask by dease translate from so