how to change form variable values from view - python

i've been trying to send data to the following form from my view.
i need the variable (choices ) to change each time we call this form
class AnswersForm(forms.Form):
question = forms.RadioSelect
CHOICES=[('sf','asdf')]
radioButton = forms.ChoiceField(choices=CHOICES, widget=forms.RadioSelect())
view.py :
def exam_attend(request,ExamName,questionNo=0):
if ExamName:
myList = [('b','a')]
forms.AnswersForm.CHOICES=myList
form = forms.AnswersForm()
variabls = RequestContext(request,{'form':form})
return render_to_response('exam_pageAttend.html',variabls)
the problem is : i need the variable (CHOICES) from the form class to change it's value in the view class ( i know i can just use CHOICES = [('b','a')] ) but i want to change it from the view since this code is only to show the problem )
any better ideas ?
thanks in advance

You can change the field choices overriding the form init method (so that it accepts a choice parameter) or you can change the field's choices after the init, depending on your needs.
First Case would be like this:
class AnswersForm(forms.Form):
radioButton = forms.ChoiceField(choices=CHOICES, widget=forms.RadioSelect())
def __init__(self, radio_choices= None, *args, **kwargs):
super(AnswersForm, self).__init__(self, *args, **kwargs)
if radio_choices is not None:
self.fields['radioButton'].choices = radio_choices
View example:
form_instance = AnswersForm(new_choices)

Related

how to show, set the value for input filed in django form using forms in html <input value={{ value}} disabled> how to do it in django forms

i'm taking values from database table in views file and has to render those values to a form in template file which is created by using the forms class and i have to show those values for some fields and make them immutable.
class OrderForm(forms.Form):
pid=forms.IntegerField()
pname=forms.CharField()
pprice=forms.FloatField()
person_name=forms.CharField(max_length=40)
emailid=forms.EmailField()
address=forms.CharField(max_length=40)
city=forms.CharField(max_length=20)
state=forms.CharField(max_length=20)
zip=forms.IntegerField()
card=forms.IntegerField()
exp= forms.DateField()
cvv=forms.IntegerField()
def order(request,pk):
pid=pk
user_name=request.user.username
qs=Product.objects.get(pid=pid)
pname=qs.pname.format()
list={'username':user_name,'pid':pid,'pname':pname}
form=OrderForm
return render(request,'order.html',{'data':list,'form':form})
i expect input filed with value that i passed by default which is immutable and when i submit i have to get same value i passed
Looks to me like you're better off using a ModelForm. It would be something like:
class OrderForm(forms.ModelForm)
class Meta:
model = Order
widgets = {
`immutable_field` : forms.TextInput(attrs={'readonly':True})
}
def order(request,pk):
pid=pk
user_name=request.user.username
qs=Product.objects.get(pid=pid)
pname=qs.pname.format()
list={'username':user_name,'pid':pid,'pname':pname}
form=OrderForm()
form.fields['immutable_field'] = "Some Value"
return render(request,'order.html',{'data':list,'form':form})
If you already have an order then you can prepopulate the fields with form=OrderForm(instance=order)
Make field as disable from Form init method and pass initial value from view section
class OrderForm(forms.Form):
pid=forms.IntegerField()
pname=forms.CharField()
pprice=forms.FloatField()
person_name=forms.CharField(max_length=40)
emailid=forms.EmailField()
address=forms.CharField(max_length=40)
city=forms.CharField(max_length=20)
state=forms.CharField(max_length=20)
zip=forms.IntegerField()
card=forms.IntegerField()
exp= forms.DateField()
cvv=forms.IntegerField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].disabled = True
self.fields['pid'].disabled = True
self.fields['pname'].disabled = True
Here in view you can pass dictionary to form as initial value of fields.
def order(request,pk):
pid=pk
user_name=request.user.username
qs=Product.objects.get(pid=pid)
pname=qs.pname.format()
initial={'username':user_name,'pid':pid,'pname':pname}
form=OrderForm(initial=initial)
return render(request,'order.html',{'data':initla,'form':form})

Overriding Form Constructor with Pre-existing Data Makes Form Un-editable

I want to override a form that I have created with existing data if the user's profile exists so that the user can edit the data they may have already submitted. My code overrides the the init method of the Form, but when the form is rendered the form has the text, but it not editable. I need it to be editable.
The form code looks as below:
class ProfileForm(forms.Form):
aboutme = forms.CharField( widget=forms.Textarea )
aboutmeprivate = forms.BooleanField(required=False)
interestsprivate = forms.BooleanField(required=False)
def __init__(self, *args, **kwargs):
super(ProfileForm, self)
self.aboutme = kwargs.pop('aboutme')
self.aboutmeprivate = kwargs.pop('aboutmeprivate')
self.interestsprivate = kwargs.pop('interestsprivate')
The call looks like:
form = ProfileForm(aboutme=exisitingprofile.aboutme, aboutmeprivate=exisitingprofile.aboutmeprivate, interestsprivate=exisitingprofile.interestsprivate)
Can anyone advise?
You need to give like this, the super should come after the self.your_field and also you are missing the __init there
class ProfileForm(forms.Form):
aboutme = forms.CharField( widget=forms.Textarea )
aboutmeprivate = forms.BooleanField(required=False)
interestsprivate = forms.BooleanField(required=False)
def __init__(self, *args, **kwargs):
self.aboutme = kwargs.pop('aboutme')
self.aboutmeprivate = kwargs.pop('aboutmeprivate')
self.interestsprivate = kwargs.pop('interestsprivate')
super(ProfileForm, self).__init__(*args, **kwargs)
By not editable you mean to say that the field is not clickable?
The solution was to modify the call to the form from the view as below:
form = ProfileForm(initial={'aboutme': exisitingprofile.aboutme,
'aboutmeprivate' : exisitingprofile.aboutmeprivate,
'interestsprivate' : exisitingprofile.interestsprivate })
I didn't need to override the constructor.

Django: Access request.GET in form to pass queryset as choices

How in Django i can access requset in form?
I need this to get data tuple to pass in choices to form.
Below init approach doesn't work: NameError: name 'request' is not defined, with self or without: self.request.GET.get('project') or request.GET.get('project')
class PostfilterForm(forms.Form):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
super(PostfilterForm, self).__init__(*args, **kwargs)
monitoring_words_to_show = Nlpmonitorword.objects.filter(monitoringwords__name = self.request.GET.get('project'))
words_list = []
for word in monitoring_words_to_show:
words_list.append((word.monitor_word, word.monitor_word))
words_list = tuple(words_list) # trying to get here tuple to pass in choises (('vk', 'vk'), ('fb', 'fb'), ('vkfb', 'vkfb'))
project = forms.CharField(required=True, label='')
monitor = forms.MultipleChoiceField(widget=forms.SelectMultiple, choices=words_list, required=False, label='')
All the code you're trying to use isn't used within a method which means it doesn't belong to any instance of a PostFilterForm and therefore has no knowledge of self let alone its fields.
You should include these in a function, although what function that should be is unclear.
def my_function(self):
monitoring_words_to_show = Nlpmonitorword.objects.filter(monitoringwords__name = self.request.GET.get('project'))
words_list = []
for word in monitoring_words_to_show:
words_list.append((word.monitor_word, word.monitor_word))
words_list = tuple(words_list) # trying to get here tuple to pass in choises (('vk', 'vk'), ('fb', 'fb'), ('vkfb', 'vkfb'))
What your form needs is not the request it's the project. It's better to deal with the request in the view and pass the required parameters to the form:
Form:
class PostfilterForm(forms.Form):
def __init__(self, project, *args, **kwargs):
self.project = project
View:
project = request.GET.get('project')
form = PostfilterForm(project, request.POST)

How to use "Readonly Field" outside Admin

I have a form that I need to show my project outside the area of administration, some fields can not be edited but can see them.
To do this would be great "AdminReadonlyField" found in "django.contrib.admin.helpers" The problem is that you can not do.
I have tried to create some widget that can replace this complex class, but I can not get it to work properly with DateTiemField fields.
class UserUpdateForm(forms.ModelForm):
"""
We need field "date_joined" can not be edited but can see them
"""
class Meta:
model = User
fields = ('first_name', 'last_name',
'email', 'date_joined', 'slug')
def __init__(self, user, *args, **kwargs):
kwargs['instance'] = user
super(UserUpdateForm, self).__init__(*args, **kwargs)
self.fields['date_joined'].widget = widgets.CMDateTimeText()
def clean_date_joined(self):
instance = getattr(self, 'instance', None)
if instance and instance.pk:
return instance.date_joined
else:
return self.cleaned_data['date_joined']
My code, something is not right.
class CMDateTimeText(DateTimeBaseInput):
"""
A SplitDateTime Widget that has some admin-specific styling.
Hereda Field and Widget.
"""
format_key = 'DATETIME_FORMAT'
def __init__(self, attrs=None, format=None):
# Use slightly better defaults than HTML's 20x2 box
default_attrs = {'class': 'date_id'}
if attrs:
default_attrs.update(attrs)
super(CMDateTimeText, self).__init__(attrs=default_attrs, format=format)
def render(self, name, value, attrs=None):
if value is None:
value = ''
value = self._format_value(value)
final_attrs = self.build_attrs(attrs, name=name)
return format_html('<p{}>{}</p>', flatatt(final_attrs), conditional_escape(value))
Result image:
any idea how to do "AdminReadonlyField"" any view or form?
So after hours of looking for various solutions, I found out how to do it the Django way.
Simply add the attribute disabled to the field in the form (not the widget!):
# in __init__() with crispy-forms for instance
self.fields['field'].disabled = True
# as form field
field = forms.CharField(disabled=True)
And it works... Django is taking care of not saving the field, if some hacker tampered with it although it's disabled. Only works with Django 1.9+.

How do I initiate values for fields in a form for editing in a template

I understand that you can use the initiate parameter for a Form class from this question.
I am creating an edit form and I'm trying to figure out how to initiate values from a pre-existing object.
Do I do it in the template level or in the view level (I don't even know how to do it in the template level)? Or maybe I need to pass the actual object to the form and initiate in the form level?
What is the best practice?
EDIT:
For #Bento: In my original Form, I'm doing something like this
class OrderDetailForm(forms.Form):
work_type = forms.ChoiceField(choices=Order.WORK_TYPE_CHOICES)
note = forms.CharField(widget=forms.Textarea)
def __init__(self, creator_list=None, place_list=None, *args, **kwargs):
super(OrderCreateForm, self).__init__(*args, **kwargs)
if creator_list:
self.fields['creator'] = UserModelChoiceField(
queryset=creator_list,
empty_label="Select a user",
)
def clean(self):
super(OrderCreateForm, self).clean()
if 'note' in self.cleaned_data:
if len(self.cleaned_data['note']) < 50:
self._errors['note'] = self.error_class([u"Please enter a longer note."])
del self.cleaned_data['note']
return self.cleaned_data
How would I do that with ModelForm?
Assuming you are using a ModelForm, it's actually fairly simple. The task is something like this: retrieve the object of the model that you want to populate your 'edit' for with, create a new form based on your ModelForm, and populate it with the object using 'instance'.
Here's the skeleton of your view:
def view(request):
obj = Model.objects.get(pk = objectpk)
form = MyModelForm(instance = obj)
return render (request, "template", {'form' = form})
You can access the 'initial' values by using something like:
form.fields['fieldname'].initial = somevalue
And then you'd return the form like above.

Categories