Совместное использование логики форм между Django Rest Framework и UI - PullRequest
0 голосов
/ 20 сентября 2018

В моем приложении django есть сущность Campaign.Для моего пользовательского интерфейса я реализовал CampaignForm, в котором есть логика, которая не является тривиальной.

Я также интегрировал Django Rest Framework, чтобы разрешить функции CRUD класса Campaign через API.

После поиска в Google и документах DRF я обнаружил, что не существует официального способа интеграции форм Django в DRF .

Должен быть, я ошибаюсь, верно?

Единственное, что я вижу, это то, что DRF имеет собственные валидаторы, но я не думаю, что он может портировать всю логику моей формыдля валидаторов DRF.

Как я могу включить логику моей CampaignForm в мой API?

Ссылка:

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'))

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Если вы хотите испачкать руки:

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))
0 голосов
/ 20 сентября 2018

Короче говоря: Фреймворк для отдыха в Django имеет serializers модуль, который эквивалентен покою forms.

. Вы должны создать Serializer (или ModelSerializer), которыйбудет обрабатывать логику так же, как в вашей CampaignForm.

Посмотрите на Сериализаторы |Django Rest Framework Docs .

...