我的django应用有一个实体Campaign
。对于我的UI,我已经实现了CampaignForm
,其逻辑并不简单。
我还集成了Django Rest Framework,以通过API允许Campaign
类的CRUD功能。
在搜索Google和DRF的文档后,我发现没有将Django Forms集成到DRF中的官方方法。
我一定弄错了吗?
我唯一看到的是DRF具有自定义验证器,但我认为它不能将表单的所有逻辑移植到DRF的验证器中。
如何在我的API中包含CampaignForm的逻辑?
参考:
class CampaignForm(forms.ModelForm):
class Meta:
model = Campaign
fields = '__all__'
help_texts = {
'dayparting_schedule': schedule_help_text
}
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super().__init__(*args, **kwargs)
def clean(self, *args, **kwargs):
"""
- All Active MUST have dayparting schedule defined
- If schedule is set then timezone must also be set
"""
cleaned_data = super().clean()
status = cleaned_data.get('status')
dayparting_schedule = cleaned_data.get('dayparting_schedule')
if status == Campaign.ACTIVE:
# if there is no existing dayparting_schedule OR
# if this form does not have dayparting_schedule
if dayparting_schedule is None \
and self.instance.dayparting_schedule is None:
raise forms.ValidationError(_('dayparting_schedule cannot be empty for Active'))
schedule_present = bool(dayparting_schedule)
timezone_present = bool(cleaned_data.get('dayparting_timezone'))
# XOR: 0^0, 1^1 => 0, otherwise 1
if schedule_present ^ timezone_present:
raise forms.ValidationError(
_('dayparting_schedule and dayparting_timezone must be set together.'))
return cleaned_data
def clean_dayparting_schedule(self, *args, **kwargs):
schedule = self.cleaned_data.get('dayparting_schedule')
if not schedule:
return
self.validate_schedule(schedule)
return schedule
def validate_schedule(self, yaml_s):
dic = yaml.load(yaml_s)
if not isinstance(dic, dict):
raise forms.ValidationError(_('Invalid Format: Please follow the format above'))
if set(dic.keys()) != set(['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']):
raise forms.ValidationError(_('Invalid Format: Missing mon/tue/wed/thu/fri/sun'))
for v in dic.values():
if not re.match('[0-9]{4}-[0-9]{4}$', v):
raise forms.ValidationError(_('Invalid Format: value must be 1200-1500'))
答案 0 :(得分:0)
简而言之: Django rest框架具有serializers
模数,其其余部分等同于Django的forms
。
您应该创建Serializer
(或ModelSerializer
),该逻辑将处理与CampaignForm
中相同的逻辑。
答案 1 :(得分:0)
如果要弄脏手:
class CampaignSerializer(serializers.ModelSerializer):
...
def validate(self, data):
"""
During updating, self.instance will be available.
"""
form = CampaignForm(data, instance=self.instance)
if form.is_valid():
return data
raise serializers.ValidationError(str(form.errors))