Passing variables when instantiating a form class using FormWizard - django

I have a simple form which uses a queryset that is set dynamically:
class FooForm(forms.Form):
bar = forms.ModelChoiceField(queryset = Bar.objects.none())
def __init__(self, queryset=None, *args, **kwargs):
super(FooForm, self).__init__(*args, **kwargs)
self.fields['bar'].queryset = queryset
I'd like to use this as one of my forms in a FormWizard, but I can't figure out how I can get FormWizard to pass on the queryset. Is this possible at all?

I think you could override the "get_form" method for that particular wizard
class MyWizard(FormWizard):
def __init__(self, *args, **kwargs):
self.querysets = kwargs.pop('querysets', None)
super(self, MyWizard).__init__(*args, **kwargs)
def get_form(self, step, data=None, *args, **kwargs):
return self.form_list[step](data, prefix=self.prefix_for_step(step), initial=self.initial.get(step, None), queryset=self.querysets.get(step, None))
def done(self, *args, **kwargs): pass

Related

How do I return a class-based view method with super from a function within that very same class-based view method?

Is it even possible?
I can't find anything or figure it out by myself since I'm a beginner, so I turn to you guys.
Here's an example (don't worry about the use case, I just want to know if it's possible and how):
When I run this code I get that *args is not defined. What's wrong?
views.py:
class MyCreateView(CreateView):
def get(self, request, *args, **kwargs):
slug = kwargs['slug']
helper_method(self, slug)
helpers.py:
def helper_method(self, slug):
if slug == "random":
return super(self.__class__, self).get(request, *args, **kwargs)
You have to define args and kwargs, you just need to add them to your method parameters like this:
def helper_method(self, slug, *args, **kwargs):
if slug == "random":
return super(self.__class__, self).get(request, *args, **kwargs)
class MyCreateView(CreateView):
def get(self, request, *args, **kwargs):
slug = kwargs['slug']
helper_method(self, slug, *args, **kwargs)

How to make a Django Model form Readonly?

I have a django form name "SampleForm". Which i use to take input from user. Now i want to use same form to show this information to user on a different page. But form is editable I want to make the form read only. Is there any way to make whole form Readonly ?
pseudo-code (not tested):
class ReadOnlyFormMixin(ModelForm):
def __init__(self, *args, **kwargs):
super(ReadOnlyFormMixin, self).__init__(*args, **kwargs)
for key in self.fields.keys():
self.fields[key].widget.attrs['readonly'] = True
def save(self, *args, **kwargs):
# do not do anything
pass
class SampleReadOnlyForm(ReadOnlyFormMixin, SampleForm):
pass
class SampleForm(ModelForm):
def __init__(self, *args, **kwargs):
super(SampleForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if instance and instance.pk:
for field in self.fields.keys():
self.fields[field].widget.attrs['readonly'] = True
Just this should make the entire form readonly whenever an instance is available for the form.
Working Code
class ReadOnlySampleForm(SampleForm):
def __init__(self, *args, **kwargs):
super(SampleForm, self).__init__(*args, **kwargs)
for key in self.fields.keys():
self.fields[key].widget.attrs['readonly'] = True
in Django 4.1, override the get_context_data with
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(object_list=None, **kwargs)
form = AddressForm(instance=self.get_object())
for name, field in form.fields.items():
field.disabled = True
context["form"] = form
return context

Display Selection from Django choicefield?

Is there a way to display the selection in Django choicefield? For example, I would like to
display the selected choice in "S". Is there an easy way to do this(build-in function)?
S_CHOICES=(('A','A'),('B','B'),('Other','Other'))
S = forms.ChoiceField(choices=select_CHOICES, initial='A')
def __init__(self, *args, **kwargs):
super(YourForm, self).__init__(*args, **kwargs)
self['S'].value()
print(S)
You can do it in form's __init__:
class YourForm(forms.Form):
S_CHOICES=(('A','A'),('B','B'),('Other','Other'))
S = forms.ChoiceField(choices=select_CHOICES)
def __init__(self, *args, **kwargs):
super(YourForm, self).__init__(*args, **kwargs)
self.fields['S'].initial = 'A'

Is it possible to use forms as fields in other forms?

I have a form that I've created in Django:
class someForm(forms.Form):...
that takes in a variable, someVariable, in its init function:
def __init__(self, someVariable, *args, **kwargs):
Is it possible for me to use someForm as a field in another form like so?:
class someOtherForm(forms.Form):
sf = someForm(someVariable=self.someVariable)
...
def __init__(self, someVariable, *args, **kwargs)
self.someVariable = someVariable
I think your best bet would be extending the original form like so:
def someForm(forms.Form):
someVariable = ...
...
def __init__(self, someVariable, *args, **kwargs):
self.someVariable = someVariable
def someOtherForm(someForm):
...
def __init__(self, someVariable, *args, **kwargs):
super(SomeOtherForm, self).__init__(someVariable, *args, **kwargs)

Django Admin: Getting request in ModelForm's constructor

The below code removes certain values from a drop down menu.
It works fine but I want to remove the value if the user lacks certain permissions.
How can I access request.user in the ModelForm's constructor? Or is there a better way to accomplish what I am trying to do?
class AnnouncementModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(AnnouncementModelForm, self).__init__(*args, **kwargs)
self.fields["category"].queryset = AnnouncementCategory.objects.filter(can_post=True)
How can I access request.user in the ModelForm's constructor?
To use it in the Form constructor, just pass the request to it.
class AnnouncementModelForm(forms.ModelForm):
def __init__(self, request, *args, **kwargs):
super(AnnouncementModelForm, self).__init__(*args, **kwargs)
qs = request.user.foreignkeytable__set.all()
self.fields["category"].queryset = qs
Ok here is how I solved it:
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "category" and not request.user.has_perm('can_post_to_all'):
kwargs["queryset"] = AnnouncementCategory.objects.filter(can_post=True)
return db_field.formfield(**kwargs)
return super(AnnouncementAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)