我有以下型號:的ModelForm和模型驗證一起玩
class Advertisement(models.Model):
slug = models.UUIDField(default=uuid4, blank=True, editable=False)
advertiser = models.ForeignKey(Advertiser)
position = models.SmallIntegerField(choices=POSITION_CHOICES)
share_type = models.CharField(max_length=80)
country = CountryField(countries=MyCountries, default='DE')
postal_code = models.CharField(max_length=8, null=True, blank=True)
date_from = models.DateField()
date_to = models.DateField()
基於廣告客戶,位置,類型國家和郵政編碼該商店的範圍date_from和DATE_TO adverisements。
advertiser, position, share_type, country and postal_code
從請求來臨,並獲取在
class CreateAdvertisment(LoginRequiredMixin, CreateView):
# Some usefull stuff
def dispatch(self, request, *args, **kwargs):
self.advertiser = Advertiser.objects.get(user=self.request.user)
self.share_type = self.kwargs.get('share_type', None)
self.country = self.kwargs.get('country', None)
self.postal_code = self.kwargs.get('postal_code', None)
self.position = int(self.kwargs.get('position', None))
self.position_verbose = verbose_position(self.position)
ret = super(CreateAdvertisment, self).dispatch(request, *args, **kwargs)
return ret
沒有檢查date_from,DATE_TO任何驗證。我可以簡單地做
def form_valid(self, form):
form.instance.advertiser = self.advertiser
form.instance.share_type = self.share_type
form.instance.country = self.country
form.instance.postal_code = self.postal_code
form.instance.position = self.position
ret = super(CreateAdvertisment, self).form_valid(form)
return ret
我完成了。不幸的是,我不能這樣做,因爲我必須檢查廣告的有效時間框架,以避免同時進行雙重預訂。我在模型中使用以下方法執行此操作:
def clean(self):
ret = super(Advertisement, self).clean()
print ("country [%s] position [%s] share_type [%s] postal_code [%s]" % (self.country,
self.position, self.share_type, self.postal_code))
if self.between_conflict():
raise ValidationError("Blocks between timeframe")
elif self.end_conflict():
raise ValidationError("End occupied")
elif self.during_conflict():
raise ValidationError("Time Frame complete occupied")
elif self.start_conflict():
raise ValidationError("Start Occupied")
return ret
def start_conflict(self):
start_conflict = Advertisement.objects.filter(country=self.country,
position=self.position,
share_type=self.share_type,
postal_code=self.postal_code).filter(
date_from__range=(self.date_from, self.date_to))
return start_conflict
這很好,我篩選出給定期間的任何衝突。問題是我沒有實例變量,因爲它們是在view.form_valid()和model.clean()中設置的,它由表單驗證過程調用。
我確實有一個雞蛋問題在這裏。我想設置請求參數的形式kwargs在
def get_form_kwargs(self, **kwargs):
kwargs = super(CreateAdvertisment, self).get_form_kwargs()
kwargs['advertiser'] = self.advertiser
kwargs['position'] = self.position
....
然後將它們放入表單實例的形式。 初始化()
def __init__(self, *args, **kwargs):
advertiser = kwargs.pop('advertiser')
position = kwargs.pop('position')
# .. and so on
super(AdvertismentCreateForm, self).__init__(*args, **kwargs)
對於一些原因,我不認爲這是很Python的。有人有更好的主意嗎?我會發布我的解決方案。
thx。 kwargs ['instance']在我的情況下是沒有的。可能是因爲它是一個創建視圖。您的提案在UpdateView中可以正常工作。我已經檢查過了。 – mbieren
如果'kwargs ['instance']'是'None',則將其替換! – Alasdair
這工作正常。非常感謝。但是,即使在CreateView.get_form_kwargs()中已經有一個有效的kwargs ['實例')會不會更好?這顯然是在UpdateView中執行的。 – mbieren