Django ModelForm, которая использует комбинацию двух полей модели в одном поле - PullRequest
0 голосов
/ 22 мая 2018

Можно ли объединить два поля модели в ModelForm для ввода в одно поле char?

Моя модель:

class Sample(models.Model):
    request_number = models.PositiveIntegerField()
    year = models.PositiveIntegerField()
    part = models.CharField(max_length=6, null=True, blank=True)

    class Meta:
        db_table = "sample"
        unique_together = (('request_number', 'year', 'part'),)

    def __str__(self):
        sample_id = "%s/%s" %(str(self.request_number), str(self.year)[2:])
        return(sample_id)

Поэтому образец возвращается из модели как / или, 123/18

Однако, если я создаю ModelForm, я не хочу, чтобы два поля вводили request_number и затем год.Вместо этого я хотел бы, чтобы одно поле char для пользователя вводило 123/18, мою форму для анализа request_number и year, а также для проверки ModelForm.

Я пробовал это как обычную форму django, но этоне проверяется на мой взгляд.

Форма:

class SingleSampleForm(forms.Form):

    sample_id = forms.CharField(
        required=True,
        label='Sample ID:')

    class Meta:
        fields = ['sample_id']

    def __init__(self, *args, **kwargs):
        super(SingleSampleForm, self).__init__()
        self.helper = FormHelper()
        self.helper.layout = Layout(
            Field('sample_id',
                css_class="search-form-label",
                ),
            Submit('submit', 'Search sample', css_class='upload-btn')
        )

        self.helper.form_method = 'POST'

    def clean(self):
        sample_id = self.cleaned_data['sample_id']
        if sample_id:
            return sample_id
        raise ValidationError('This field is required')

views.py:

class SampleView(View):

    sample_form = SingleSampleForm

    def get(self, request, *args, **kwargs):

        sample_form = self.sample_form()
        self.context = {'sample_form': sample_form,}

        return render(request,
                'results/single_sample_search.html',
                self.context)

    def post(self, request, *args, **kwargs):
        sample_form = self.sample_form(request.POST)

        if sample_form.is_valid():
            print('Valid')
        else:
            print('not valid')

        self.context = {'sample_form': sample_form,}

        return render(request,
                'results/single_sample_search.html',
                self.context)

Можно ли использовать django ModelForm и создать поле, котороетакое сочетание двух, которое затем можно проанализировать и проверить в методах "clean_request_number" и clean_year "? Или почему я ошибаюсь в этой пользовательской форме?

Спасибо

1 Ответ

0 голосов
/ 23 мая 2018

На моей машине работал следующий код: ubuntu18.04 + python3.6.5 + django2.0 + pipenv:

models.py

from django.db import models
from django.urls import reverse


class Sample(models.Model):
    request_number = models.PositiveIntegerField()
    year = models.CharField(max_length=4, blank=True)
    part = models.CharField(max_length=6, null=True, blank=True)

    class Meta:
        db_table = "sample"
        unique_together = (("request_number", "year", "part"),)

    def get_absolute_url(self):
        return reverse("sample-detail", args=[self.pk])

    def __str__(self):
        return f"{self.request_number}/{self.year[-2:]}"

forms.py

from django import forms
from django.core.validators import RegexValidator
from .models import Sample


class SingleSampleForm(forms.Form):
    sample_str = forms.CharField(
        required=True, label="Sample(request_number/year):",
        validators=[
            RegexValidator(r'^\d+/\d{2,4}$', "Sample should be as `123/18`")
        ]
    )

    class Meta:
        model = Sample

views.py

from django.shortcuts import render
from django.views.generic.detail import DetailView
from django.views.generic.edit import FormView
from .forms import SingleSampleForm


class SampleCreateView(FormView):
    template_name = "results/sample_create.html"
    form_class = SingleSampleForm

    def get_success_url(self):
        return self.object.get_absolute_url()

    def form_valid(self, form):
        request_number, year = form.cleaned_data['sample_str'].split("/")
        if len(year) == 2:
            year = "20" + year
        self.object = form.Meta.model.objects.create(
            request_number=request_number, year=year
        )
        return super().form_valid(form)


class SampleDetailView(DetailView):
    template_name = "results/sample_detail.html"
    queryset = SingleSampleForm.Meta.model.objects.all()

results / sample_create.html

<form method="post">{% csrf_token %}
    {{ form }}
    <input type="submit" value="OK">
</form>

results / sample_detail.html

<p>request number: {{ object.request_number }}</p>
<p>year: {{ object.year }}</p>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...