Django modelform - 制作一个modelform,提供基于其他模型的选择

Django modelform - make a modelform that provides a choice based on other models

我想要一个名为 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 对象的实例 - 不是 VariantAnnotationSampleRun 对象 - 因此表单集无效。

但是我试图从头开始创建一个 VariantAnnotationSampleRun 对象 - 没有 VariantAnnotationSampleRun id - 这就是我想要做的,但是同时使用 sample_run_id 和 variant_annotation_id (外键链接到这些表)

当我在字段列表中包含 variant_annotation_id 时 - 表单会在下拉列表中生成所有 variant_annotation_id。

我很困惑 - 谁能帮助我更好地理解如何从模型表单制作模型实例,以及我是否以完全错误的方式进行处理

谢谢

你的问题有点混乱...所以我会在这里尽可能具体...

1 - 我想制作一个模型,它将创建一个 VariantAnnotationSampleRun 实例

在您的应用程序中构建一些视图并通过 AJAX 调用它,然后在您的视图中创建您想要的姿势并将其作为 ajax 响应返回给您的模板...所以编辑HTML 如果你想在创建模型时显示任何不同的东西......(喜欢标记复选框

Obs.:这有点奇怪,当用户只需单击一个简单的复选框时,您会在数据库中保留一个新对象...这样他们就可以单击它并关闭页面,这会弄脏您的数据库....

2 - 我这样做是否正确作为 VariantAnnotationSampleRun 模型形式

取决于你想要达到的目标,如果你认为有必要继续

3 - 但 'id' 是 VariantAnnotation 对象的对象 - 不是 VariantAnnotationSampleRun 对象 - 因此表单集无效。

您首先必须在后台创建此对象,然后才能访问 ID...因此,如果表单无效且未保存,则此表单不存在于您的数据库中。 (按照我之前说的 ajax 为你解决这个问题)

4 - 没有 VariantAnnotationSampleRun id - 这就是我想要做的

制作你的外键 blank=Truenull=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/

建议:我猜你想用这个变体做一些疯狂的事情......也许你应该把简单的 select 放在你的 html,并从此选项中获取 ID selected 并在表单有效时执行您的逻辑

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