在一个字符字段中使用两个模型字段组合的 Django ModelForm
Posted
技术标签:
【中文标题】在一个字符字段中使用两个模型字段组合的 Django ModelForm【英文标题】:Django ModelForm that uses a combination of two model fields in one charfield 【发布时间】:2018-11-01 00:32:33 【问题描述】:是否可以将 ModelForm 中的两个模型字段组合到一个字符字段中?
我的模特:
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 和年份。相反,我想要一个字符域供用户输入 123/18, 我的表单来解析 request_number 和年份,并验证 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“方法中对其进行解析和验证?或者为什么我在这个自定义表单中出错了?
谢谢
【问题讨论】:
似乎您需要自定义小部件。 ***.com/questions/4707192/… 【参考方案1】:以下代码在我的机器上运行,即 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+/\d2,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()
结果/sample_create.html
<form method="post">% csrf_token %
form
<input type="submit" value="OK">
</form>
结果/sample_detail.html
<p>request number: object.request_number </p>
<p>year: object.year </p>
【讨论】:
以上是关于在一个字符字段中使用两个模型字段组合的 Django ModelForm的主要内容,如果未能解决你的问题,请参考以下文章