I am trying to display all the models that are related to another model in a modal box when a user clicks on a button. However, the Update view is not working how I want it to work. I am getting a Not Found for the URL pattern related to the class based view (Model Object UpdateView) instead of 200 OK
I tried several approaches, but below is the latest one. When I do a print out of the get_queryset (that I have override), I get the objects. I tried to print the context['formset'], but it seems like the code didn't reach that far.
I am using django-bootstrap-modal-forms 1.4.2 to display model formsets and I am using django-polymorphic 2.1.2 to deal with polymorphism of the models. The reason why I am using this approach are: 1. There is a many to many relationships between a modelflow and a model object. 2. Using the modal box would make a cleaner interface, instead of have both the modelflow and modelobject on the same page. 3. I want to have the polymorphic approach deals with the objects that is related to a modelflow.
models.py - There are two main models that are polymorphic models ModelFlow & ModelObject along with their sub-classes.
class ModelFlow(PolymorphicModel):
decription = models.CharField(max_length=250)
relatedModelObject = models.ManyToManyField('ModelObject', through='ModelFlowObject', null=True, blank=True)
class ModelBFlow(ModelFlow):
modelflGroup = models.ForeignKey(BasicFlowGroup, on_delete=models.CASCADE, null=True, blank=True)
class ModelAFlow(ModelFlow):
modelflGroup = models.ForeignKey(BoundedFlowGroup, on_delete=models.CASCADE, null=True, blank=True)
class ModelObject(PolymorphicModel):
objectName = models.CharField(max_length=250)
class ModelFlowObject(PolymorphicModel):
flowModel = models.ForeignKey(ModelFlow, on_delete=models.CASCADE)
objectModel = models.ForeignKey(ModelObject, on_delete=models.CASCADE)
class WebPageObject(ModelObject):
objectValue = models.CharField(max_length=3, choices=WEBPAGEVALUE_CHOICES)
class LinkObject(ModelObject):
paramType = models.CharField(max_length=3, choices=WEBPAGEVALUE_CHOICES)
linkType = models.CharField(max_length=3, choices=WEBPAGEVALUE_CHOICES)
forms.py - I create the two forms based on the WebPageObject & LinkObject both inherits from ModelObject (a polymorphic model) I then created a polymorphic modelformset.
class ModelWebPageObjectForm(ModelForm):
class Meta:
model = WebPageObject
fields='__all__'
class ModelLinkObjectForm(ModelForm):
class Meta:
model = LinkObject
fields = '__all__'
Oformset = polymorphic_modelformset_factory(ModelObject,formset_children=(
PolymorphicFormSetChild(WebPageObject, form=ModelWebPageObjectForm, fields = '__all__'),), fields='__all__',extra=1)
PolymorphicFormSetChild(LinkObject, form=ModelLinkObjectForm, fields = '__all__'),
views.py - In this view, I have a used the ModelObject (a polymorphic model) as the model for the updateview. I then created a form_class with model/form pairs
class DisplayModelFlow(Updateview):
....
#this view is already working. It displays all the modelflow that is related to another model. Here I am using inlineformset.
class ModelObjectUpdateView(BSModalUpdateView):
#in this view the self.kwargs['pkObj'] from the urls.py will be used to get the modelflow object. Next, modelflow is used to find the all the modelobject (webpage or link) that are related to this. So, I am using a polymorphic modelformset to display all the modelobjects in the modal box.
model=ModelObject
form_class = {WebPageObject:ModelWebPageObjectForm,
LinkObject:ModelLinkObjectForm,
}
template_name = 'modalPopUp/updateModelObject.html'
success_message = 'Success: Object(s) Updated.'
def get_form_class(self):
return self.form_class[self.object.__class__]
'''def get_object(self):
flowmodel=ModelFlow.objects.filter(id=self.kwargs['pkObj'])
return flowmodel[0]'''
def get_queryset(self):
flowmodel=ModelFlow.objects.filter(id=self.kwargs['pkObj'])
myobj=flowmodel[0].relatedModelObject.all()
return myobj
def get_context_data(self, **kwargs):
context = super(ModelObjectUpdateView, self).get_context_data(**kwargs)
if self.request.POST:
context['formset'] = Oformset(queryset=self.get_queryset())
else:
context['formset'] = Oformset(queryset=self.get_queryset())
return context
def post(self, request, *args, **kwargs):
formset = Oformset(self.request.POST)
if (formset.is_valid()):
return self.form_valid(formset)
else:
return self.form_invalid(formset)
def form_valid(self, formset):
self.object = formset.save()
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, formset):
return self.render_to_response(self.get_context_data(formset=formset))
def get_success_url(self):
self.success_url = reverse_lazy('recSys:FlowRecSysList', kwargs={'project': self.kwargs['project'],
'useCaseName': self.kwargs['useCasename']})
return self.success_url
urls.py - This is the url updateview gets.
...
path('<str:project>/UCModelUpdate/<int:pk>/updateModelObject/<str:pkObj>', ModelObjectUpdateView.as_view(), name='updateModelObject'),
...
template
There is a .html to display the modelFlow along with a button that when is clicked displays the modal box for the objects will be displayed. There may be several modelFlows on the .html along with a button for the modal box that should display only the modelobjects that are related to it.
The expected result should be a modal box with the all the allows based on the queryset in the context['formset']. Also, GET should be 200 OK.
However, I am getting this message:
Not Found: /useCaseExtract/Marvel-E-Store/UCModelUpdate/2/updateModelObject/319/
[15/Sep/2019 12:26:41] "GET /useCaseExtract/Marvel-E-Store/UCModelUpdate/2/updateModelObject/319/ HTTP/1.1" 404 5459
and no modal box is being displayed.