Django Form inheritance problem - python

Why can't I do this?
from django import forms
from django.forms import widgets
class UserProfileConfig(forms.Form):
def __init__(self,*args,**kwargs):
super (UserProfileConfig,self).__init__(*args,**kwargs)
self.tester = 'asdf'
username = forms.CharField(label='Username',max_length=100,initial=self.tester)
More specifically, why cant the forms.CharField grab the variable tester that I set during construction?
I feel like I am missing something about the way Python handles this sort of thing...
edit :
What I am actually trying to do is this:
class UserProfileConfig(forms.Form):
def __init__(self,request,*args,**kwargs):
super (UserProfileConfig,self).__init__(*args,**kwargs)
self.tester = request.session['some_var']
username = forms.CharField(label='Username',max_length=100,initial=self.tester)
In other words, I need to grab a session variable and then set it to an initial value...
Is there any way to handle this through the __init__ or otherwise?

What you've got doesn't work because your CharField gets created, and pointed to by UserProfileConfig.username when the class is created, not when the instance is created. self.tester doesn't exist until you call __init__ at instance creation time.

You can just do it this way
from django import forms
from django.forms import widgets
class UserProfileConfig(forms.Form):
username = forms.CharField(label='Username',max_length=100,initial=self.tester)
tester = 'asdf'

You could do this:-
class UserProfileConfig(forms.Form):
username = forms.CharField(label='Username',max_length=100)
def view(request):
user_form = UserProfileConfig(initial={'username': request.session['username',})
Which is the generally accepted method, but you can also do this:-
class UserProfileConfig(forms.Form):
def __init__(self,request,*args,**kwargs):
super (UserProfileConfig,self).__init__(*args,**kwargs)
self.fields['username'] = request.session['some_var']
username = forms.CharField(label='Username',max_length=100)
def view(request):
user_form = UserProfileConfig(request=request)

Related

How to get request value in another class in django?

It's an example that's as similar as possible, and it's not exactly the same as the actual code.
But I believe it's easy to understand.
class Fruits:
...
def get_sample_data(self, df):
...
data = {
'put_file_attachment': >here<,
}
...
class DataInputForm(forms.Form):
attachment = forms.FileField()
class MyView(FormView):
template_name = 'view.html'
form_class = DataInputForm
def get_success_url(self):
return str(
reverse_lazy("milk")
)
def post(self, request, *args, **kwargs):
get_file = request.FILES.get('attachment')
...
k = Fruits()
k.load_data()
return self.render_to_response(context)
I would like to bring the attachment(In fact, get_file) that the user attached to the web class Fruits's >here<
In other words, I would like to save the file(get_file) in DB column (put_file_attachment) by the user's attachment. How can I get a value passed to a request from another class to another class?
I tried to get 'get_file' by creating a MyView object in the Fruit class, but it doesn't work.
Is that possible in this structure or Am I not understanding the concept of request??
The variable must be explicitly passed to the class for it to be available. It's currently in a different scope, so it won't be available.
So, either refactor your Fruits class to take your file as an argument to your constructor (ie, __init__), or pass it in some other way, such as a parameter to your load_data method.

Django CreateView - How do I call form class __init__?

I have a django create view and I want to call the __init__ of the form class and I don't know how to do that.
class PersonCreateView(CreateView):
model = Person
form_class = PersonForm
In the form class I made some logic to redefine the queryset of some combos. My problem is that I don't know how to call the __init__ method, or any other method, of the PersonForm
Thanks in advance for any help.
You shouldn't call it yourself. You can override get_form_kwargs to provide extra arguments to pass to the form instantiation.
class PersonCreateView(CreateView):
model = Person
form_class = PersonForm
def get_form_kwargs(self, *args, **kwargs):
form_kwargs = super(PersonCreateView, self).get_form_kwargs(*args, **kwargs)
form_kwargs['my_extra_queryset_param'] = get_my_extra_queryset()
return form_kwargs
The init method is actually called automatically by the class when a new instance of the object is instantiated.
Consider the following example:
class House():
__init__(self,x,y):
self.x = x
self.y = y
self.z = x*y
To call init, we just do the following:
h = House(5,7)
This will create the object and automatically invoke the init function. It works the same way for django views.
I see Daniel beat me to an answer, perhaps his is more what you're looking for. Anyways, hope this helps a little at least!

Overriding a function in python

I have the following base class (code shortened):
class SignupForm(GroupForm):
username = forms.CharField(
label = _("Username"),
max_length = 30,
widget = forms.TextInput()
)
def __init__(self, *args, **kwargs):
super(SignupForm, self).__init__(*args, **kwargs)
if REQUIRED_EMAIL or EMAIL_VERIFICATION or EMAIL_AUTHENTICATION:
self.fields["email"].label = ugettext("Email")
self.fields["email"].required = True
else:
self.fields["email"].label = ugettext("Email (optional)")
self.fields["email"].required = False
def after_signup(self, user, **kwargs):
"""
An extension point for subclasses.
"""
pass
What I wanna do is override the after_signup() function and the username field like so:
class CompanySignupForm(SignupForm):
#TODO: override fields for company signup form
username = forms.CharField(
label = _("Username TEST"),
max_length = 30,
widget = forms.TextInput()
)
def after_signup(self, user, **kwargs):
"""
An extension point for subclasses.
"""
print str('after_signup is has been overwritten')
My Problem:
Only the username field shows the desired behavior. The after_signup() function get never called. Instead the after_signup() function of the base class SignupForm gets called. What am I doning wrong?
EDIT:
the imports:
from django import forms
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _, ugettext
instantiating CompanySignupForm:
url(r"^signup/$", CompanySignupForm.as_view(), name="acct_signup")
after_signup() is beeing called from a function in the base class:
def save(self, request=None):
# more code here
# ...
self.after_signup(new_user)
Use isinstance() to check an instance’s type and .__class__ to make sure you are instantiating CompanySignupForm.
Also you might want to create an __init__ method on the CompanySignupForm to ensure it's not just instantiating the super class.
Note: Reading your edit more closely your not calling after_signup directly the base class function save is right? This will then call it's local method after_signup if it exists. I'd take that function out of the base class and force it to call the inherited functions
To check the version run:
signup = CompanySignupForm.as_view()
print signup.__class__
url(r"^signup/$", signup, name="acct_signup")

Django ModelForm Meta

I want create a ModelForm class where model is a parameter passed from the view.(i want a dynamic form, so i can create all forms using the same class ObjectForm by just changing model value in Meta) :
class ObjectForm(ModelForm):
model_name = None
def __init__(self, *args, **kwargs):
model_name = kwargs.pop('model_name ')
super(ModelForm, self).__init__(*args, **kwargs)
class Meta:
model = models.get_model('core', model_name )
exclude = ("societe")
An error is occured and say that model_name is not a global field.
Please help me on this problem.
your problem is that the class (and the Meta class) are processed at compile time, not when you instantiate your ObjectForm. at compile time, the model name is unknown. creating classes dynamically is possible, but a bit more complicated. as luck has it, the django devs have done the hard work for you:
>>> from django.forms.models import modelform_factory
>>> modelform_factory(MyModel)
<class 'django.forms.models.MyModelForm'>
update
So you want something like
def my_view(request):
# ...
MyForm = modelform_factory(MyModel)
form = MyForm(request.POST) # or however you would use a 'regular' form
Well, your basic error is that you are accessing model_name as a local variable, rather than as a model instance. That's fairly basic Python.
But even once you've fixed this, it still wouldn't work. The Meta class is evaluated at define time, by the form metaclass, rather than at runtime. You need to call forms.models.modelform_factory - you can pass in your modelform subclass to the factory, if you want to define some standard validation and/or fields.
form_class = modelform_factory(MyModel, form=MyModelForm)

Django - Access request.session in form

I am calling a form as follows, then passing it to a template:
f = UserProfileConfig(request)
I need to be able to access the request.session within the form... so first I tried this:
class UserProfileConfig(forms.Form):
def __init__(self,request,*args,**kwargs):
super (UserProfileConfig,self).__init__(*args,**kwargs)
self.tester = request.session['some_var']
username = forms.CharField(label='Username',max_length=100,initial=self.tester)
This didn't work, I gather, because of when the form is constructed compared to setting the username charfield.
So, next I tried this:
class UserProfileConfig(forms.Form):
def __init__(self,request,*args,**kwargs):
super (UserProfileConfig,self).__init__(*args,**kwargs)
self.a_try = forms.CharField(label='Username',max_length=100,initial=request.session['some_var'])
username = self.a_try
To no avail.
Any other ideas?
Try this:
class UserProfileConfig(forms.Form):
def __init__(self,request,*args,**kwargs):
super (UserProfileConfig,self).__init__(*args,**kwargs)
self.fields['username'] = forms.CharField(label='Username',max_length=100,initial=request.session['some_var'])
I find this article about dynamic forms very helpful.
I am so surprised that Django use session in form is so hard. sometimes we really need use session data in form to valid fields.
I create a small project can solve this. django-account-helper
example code:
from account_helper.middleware import get_current_session
Class YourForm(forms.Form):
def clean(self):
session = get_current_session()
if self.cleaned_data.get('foo') == session.get('foo'):
# do something
pass
#... your code
pass

Categories