0

Edit: It appears that the problem I'm experiencing is directly related to the formset_factory() call. For some reason or other, I have been unable to access the kwargs from the view if I pass the form through the function.

I'm building a web app that utilizes high normalization in the data-structure. There are many many-to-many and one-to-many relationships to prevent excess null records and database-bloat. I want to add more entries to a model while excluding existing entries from the model.choice field.

my code looks like this: the form:

class ExtraAddForm(forms.ModelForm):
    def __init__(self, url_kwarg, *args, **kwargs):
        super(ExtraAddForm, self).__init__(self, *args, **kwargs)
        list_to_exclude = []
        query_target = models.Model.objects.get(fk_id=url_kwarg)
        for object in query_target:
            list_to_exclude.append(object.fk_id.id)
        new_queryset = models.Model.objects.exclude(fk_id__in=list_to_exclude)
        self.fields['fk_id'].queryset= new_queryset
    class Meta:
       model = models.Model
       fields= ['fk_id','field_b'}

the view:

class AddOjbectsView(FormView): 


    formset = formset_factory(ExtraAddForm(url_kwarg), can_delete=True)
    model = models.Model
    url_kwarg = 'url_kwarg'
    form_class = formset
    template_name = 'some-template.html'
    extra_context = {'some_object': models.Model2.objects.all,
                     'model_object': models.Model.objects.all,
                     'formset': formset,
                     'view_type_create': True
                     }

    def __init__(self, *args, **kwargs):
         kwargs['url_kwarg']= self.kwargs.get(self.url_kwarg)
         super().__init__(self,*args,**kwargs)

    def get(self, request, *args, **kwargs):
        request.session['url_kwarg'] = self.kwargs.get(self.url_kwarg)
        return super().get(self, request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        #this works so I'm not re-typing it


    def get_context_data(self, **kwargs):
        """Insert the form into the context dict."""

        if 'url_kwarg' not in kwargs:
            kwargs['url_kwarg'] = self.kwargs.get(self.url_kwarg)
        return super().get_context_data(**kwargs)
        #this works, but only in the get_context. Its not working as a solution to my problem.

    def get_success_url(self):
        #this works, not re-typing

My template has Javascript to handle multiple formsets, and I've tested it with a non-dynamic queryset. The only piece I'm having trouble with is taking the keyword argument from the URL and passing it to the form at init.

Lunaugh
  • 25
  • 7

2 Answers2

0

Have you tried using FormView.get_form_kwargs method? Its described in docs

class AddOjbectsView(FormView): 
    def get_form_kwargs(self):
        form_kwargs = super().get_form_kwargs()
        form_kwargs['url_kwarg'] = self.kwargs['url_kwarg']
        return form_kwargs
Kamil Niski
  • 4,580
  • 1
  • 11
  • 24
  • I have not tried that, I'm going to today. I'll let you know and accept your answer if it works! – Lunaugh Nov 07 '19 at 15:10
  • So far it hasn't been a solution. I keep running into an error where either the kwarg['key'] returns the default string instead of the integer from the URL, or "FormClass has no attribute kwargs". I've tried getting the kwarg on the FormClass, and I've tried passing the form to the FormClass from the ViewClass. I can't seem to figure out how to get the to plug in early enough in the build process to avoid the errors. – Lunaugh Nov 07 '19 at 17:22
  • Going to try with FormView.get_initial method – Lunaugh Nov 07 '19 at 17:38
  • Still no luck. Looking to see if theres another way to achieve my desired result, like a javascript workaround – Lunaugh Nov 12 '19 at 19:49
0

It would seem that the answer to my problem is to deprecate the process in favor of session variables at form validation, making use of the clean data functions. My methods above were generated from ignorance of the order of django operations, and shouldn't preoccupy anyone any further.

Lunaugh
  • 25
  • 7