我想要一个名为AddManualVariantForm的ModelForm,它是我的模型VariantAnnotationSampleRun的模型。
此模型是链接到VariantAnnotation和SampleRun模型的外键:
class VariantAnnotationSampleRun(models.Model):
variant_annotation_id = models.ForeignKey(VariantAnnotation,
on_delete=models.CASCADE, db_column='variant_annotation_id')
sample_run_id = models.ForeignKey(SampleRun,
on_delete=models.CASCADE, db_column='sample_run_id')
我想制作一个将创建VariantAnnotationSampleRun实例的模型窗体。基本上,我想在页面上显示与1个SampleRun相关的5个“ VariantAnnotation”实例,如果用户选择了一个复选框,则创建一个VariantAnnotationSampleRun实例。
首先-我是否以VariantAnnotationSampleRun模型形式这样做是正确的?
这是我目前正在尝试的内容:
forms.py:
class AddManualVariantForm(forms.ModelForm):
report = forms.ChoiceField(
choices =(
("dontreport", '-'),
("report" , 'Report'),
("toconfirm", 'To confirm')
),
label = 'report'
)
class Meta:
model = VariantAnnotationSampleRun
fields = ('id', 'report')
def __init__(self, *args, **kwargs):
sample_obj = kwargs.pop('sample_obj', None)
super(AddManualVariantForm, self).__init__(*args, **kwargs)
views.py:
class VariantSampleRunList(LoginRequiredMixin, View):
addvariantform = AddManualVariantForm
def get(self, request, *args, **kwargs):
va_lst = [..list of VariantAnnotation IDs I want to include...]
FormSet = modelformset_factory(
VariantAnnotationSampleRun,
form=self.addvariantform,
extra=0
)
formset = FormSet(
queryset = VariantAnnotation.objects.filter(id__in=va_lst),
# form_kwargs={'sample_run_obj':sample_run_obj}
)
这将以格式集显示我要在页面上显示的VariantAnnotation实例,但是'id'是VariantAnnotation对象的ID-不是VariantAnnotationSampleRun对象-因此该格式集无效。
但是我试图从头创建一个VariantAnnotationSampleRun对象-没有VariantAnnotationSampleRun id-我正在尝试创建它,但是同时使用了sample_run_id和variant_annotation_id(指向这些表的外键)
当我在字段列表中包含variant_annotation_id时,该表单会在下拉列表中生成所有variant_annotation_id。
我很困惑-有人可以帮助我更好地了解如何从模型表单中创建模型实例,以及如果我以完全错误的方式进行操作
谢谢
答案 0 :(得分:0)
您的问题有点令人困惑...所以在这里我将尽可能具体...
1-我要创建一个模型表单,该模型表单将创建VariantAnnotationSampleRun实例
在您的应用程序上构建一些视图,并通过AJAX进行调用,然后在您的视图中创建所需的姿态并将其作为ajax响应返回给模板...因此,如果您想在显示时显示任何不同的内容,请编辑HTML模型已创建...(像一样标记复选框)
糟糕:当用户仅单击一个简单的复选框时,您在数据库中保留了一个新对象,这有点奇怪……他们可以单击它并关闭页面,这会使数据库变脏。...
2-以VariantAnnotationSampleRun模型形式进行操作是否正确
取决于您要实现的目标,如果您认为有必要继续前进
3-但是'id'是VariantAnnotation对象的ID-不是VariantAnnotationSampleRun对象-因此该表单集无效。
在能够访问ID之前,您必须首先在后端创建此对象...因此,如果该表单无效且未保存,则不会存在于数据库中。 (做我在为您解决此问题之前所说的ajax内容)
4-没有VariantAnnotationSampleRun id-我正在尝试制作的
使您的外键blank=True
和null=True
可以有效地传递表单(并且无需此variantannotaiton实例即可保存),但是您可以通过保存先前的键来处理此事情来自ajax的数据(如我之前所说),或者在保存表单时仅创建一个新数据...(这样,您将需要在模型中进行自定义输入以识别用户想要做什么,然后从头开始创建模型并保存,这样您就可以获取ID)
variant, created = VariantAnnotationSampleRun.objects.get_or_created(...) # The ... means your fields
variant.id // Acessing the id
5-有人可以帮助我更好地了解如何从模型表单制作模型实例
这很简单
from django.forms import ModelForm
from myapp.models import Article
# Create the form class.
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['pub_date', 'headline', 'content', 'reporter']
# Creating a form to add an article.
form = ArticleForm()
# Creating a form to change an existing article.
article = Article.objects.get(pk=1)
form = ArticleForm(instance=article)
来源:https://docs.djangoproject.com/en/2.0/topics/forms/modelforms/
建议:我想您尝试使用此Variant做一些疯狂的事情...也许您应该在HTML中放入简单的select,然后从此选项中获取ID并执行表格有效时的逻辑
from django.http import Http404
def new(request):
if request.method == 'POST': # If the form has been submitted...
form = ArticleForm(request.POST) # A form bound to the POST data
if form.is_valid():
# Here you gonna do your logic...
# Get your variant option selected id and create your Variant instance
# Get this new variante instance and place at your model that depends on it
else:
# Do something in case if form is not valid
raise Http404
else:
# Your code without changes