Reputation: 969
I want a ModelForm called AddManualVariantForm which is a modelform of my model VariantAnnotationSampleRun.
This model is foreign key linked to VariantAnnotation and SampleRun models:
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')
I want to make a modelform which will CREATE a VariantAnnotationSampleRun instance. Basically, I want to display 5 'VariantAnnotation' instances in relation to 1 SampleRun on my page, and if the user selects a checkbox, create a VariantAnnotationSampleRun instance.
Firstly - am i correct in doing this as a VariantAnnotationSampleRun modelform?
Here is what I am trying at the moment:
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}
)
This displays the VariantAnnotation instances I want on my page, in a formset, but the 'id' is that of a VariantAnnotation object - NOT a VariantAnnotationSampleRun object - therefore the formset is not valid.
However I am trying to CREATE a VariantAnnotationSampleRun object from scratch - there is not VariantAnnotationSampleRun id - that is what im trying to make, but using both sample_run_id and variant_annotation_id (foreign key links to these tables)
When I include variant_annotation_id in my fields list - the form generates ALL variant_annotation_ids in a drop down.
I am very confused - can someone help me better understand how to make an model instance from a model form, and if I'm going about it in completely the wrong way
thanks
Upvotes: 0
Views: 131
Reputation: 2223
You question is a little bit confuse... so i'll be as specific as possible here...
1 - I want to make a modelform which will CREATE a VariantAnnotationSampleRun instance
Build some views at your app and call it by AJAX, and in your views create the stance that you want and give it back to your template as ajax response... so edit the HTML if you want to show anything diferent when model is created... (like mark the checkbox)
Obs.: Its kinda weird you persist one new object in your database when user just click a simple checkbox... so they can just click it and close the page and it will dirty you database....
2 - am i correct in doing this as a VariantAnnotationSampleRun modelform
Depends in what you trying to achieve, if you think it is necessary go ahead
3 - but the 'id' is that of a VariantAnnotation object - NOT a VariantAnnotationSampleRun object - therefore the formset is not valid.
You first must hit your backend to create this objects before you be able to acess the ID... so if the form isnt valid and not saved this do not exis in your database. (doing the ajax thing i said before fix this issue for you)
4 - there is not VariantAnnotationSampleRun id - that is what im trying to make
Make your foreign keys blank=True
and null=True
so that way you can pass in form is valid (and will be able to save without this variantannotaiton instance) but you handle this thing with getting the previous saved data from ajax (like i said before) or just making a new one when saving form... (that way you will need to make custom input in your models to identify what the user want to do, and then creating the model from scratch and saving, so you will be able to get the id)
variant, created = VariantAnnotationSampleRun.objects.get_or_created(...) # The ... means your fields
variant.id // Acessing the id
5 - can someone help me better understand how to make an model instance from a model form
Its a pretty simple thing to do
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)
Source: https://docs.djangoproject.com/en/2.0/topics/forms/modelforms/
Suggestion: I guess you trying to do a little crazy thing with this Variant... maybe you should just put simple select in your html, and get the ID from this option selected and do your logic when you form is valid
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
Upvotes: 1