Python pass instance of itself as an argument to another function - python

I have a UserModel class that will essentially do everything like login and update things.
I'm trying to pass the instance of itself (the full class) as an argument to another function of another class.
For example: (obviously not the code, but you get the idea)
from Car import CarFactory
class UserModel:
def __init__(self,username):
self.username = username
def settings(self,colour,age,height):
return {'colour':colour,'age':age,'height':height}
def updateCar(self,car_id):
c = CarFactory(car_id, <<this UserModel instance>>)
So, as you can see from the very last line above I would like to pass an instance of UserModel to the CarData class, so when within the CarData class I can access the UserModel.settings(), however, I am unsure of the syntax. I could of course just do:
c = CarFactory(car_id,self.settings)
Any help would be grateful appreciated.
Thanks

c = CarFactory(car_id, self)
doesnt work?
on a side note it would be self.settings() not self.settings ... unless you define settings to be a property

Related

How can I pass data into a class in python?

I am using django to create a blog editing page. However, my struggles do not involve django, rather just python. I have a class:
class EditForm(forms.Form):
def __init__(self, initcontent):
self.initcontent = initcontent
title = forms.CharField(max_length=100, label='Post Title')
short_description = forms.CharField(widget=forms.Textarea(attrs={"rows":3, "cols":100}))
content = forms.CharField(widget=CKEditorWidget(), initial=Post.objects.get(pk=initcontent).content)
and I am initialising it like this:
form = EditForm()
form.initcontent = post.pk
however I get the error:
File "C:\Users\Rayyan Admin\Documents\GitHub\shaista-s-cooking-blog\blogger\forms.py", line 34, in EditForm
content = forms.CharField(widget=CKEditorWidget(), initial=Post.objects.get(pk=initcontent).content)
NameError: name 'initcontent' is not defined
How do i pass initcontent into the class?
Hi your indenting is off so I'm not sure if that's a mistake in formatting here or causing issues with your code.
Anyways I think what you want is:
class EditForm():
def __init__(self, initcontent):
self.initcontent = initcontent
form = EditForm(post.pk)
Whenever you make an instance of a class, you can pass your data into it if you have defined a constructor. That is the role of a constructor. In your case, you have defined a constructor with initcontent as a parameter. So you can do it like this -
form = EditForm(whatever you need to pass)
This will do.

Dynamically reload django-filter (Model)ChoiceFilters drop-down contents

I'm using a django-filter to present a drop-down list (using ModelChoiceFilter). I'm wanting to re-load the drop down contents dynamically when the user selects a certain option (that is stored in the session; not shown in the code below). Unfortunately I'm not having any luck in achieving this. I seem to be unable to address the class (as opposed to the instance) variable that defines the drop-down list. This is what I have so far (AnotherModel contains a ForeignKey relationship to MyModel)
(filter.py)
import django_filters
class MyFilter(django_filters.FilterSet)
drop_down = ModelChoiceFilter(queryset = MyModel.objects.filter(filter1))
i = 3 # A non-filter class variable
def __init__(self, *args, **kwargs):
self.drop_down = ModelChoiceFilter(queryset = MyModel.objects.filter(filter2))
self.i = 5
#classmethod
def class_method(cls):
# Throws AttributeError; type object 'MyFilter' has no attribute 'drop_down'
<edit: printing drop-down throws the error; assigning to it works>
print cls.drop_down
cls.drop_down = ModelChoiceFilter(queryset = MyModel.objects.filter(filter2))
cls.i=4 # Works fine
(views.py)
from project.filters import MyFilter
def my_filter(request):
print MyFilter.i # prints 3
# Throws AttributeError; type object 'MyFilter' has no attribute 'drop_down'
print MyFilter.drop_down
f =MyFilter(request.GET,
queryset = AnotherModel.objects.filter(xyz))
print MyFilter.i # prints 3
print f.i # prints 5 (as expected)
# Renders a drop-down populated with the values from filter1, not filter2
return render(request,'template.html', {'filter' : f})
I had initially hoped the re-assigning the instance of drop_down would work, but since that didn't I started looking at the class variable. However it's unclear to me why I'm unable to access the class variable; in both cases where its addressed directly through MyFilter.drop_down and through the #classmethod function it throws an AttributeError, that the type object 'MyFilter' has no attribute 'drop_down'. As shown above I can access the class variable i as expcted.
Is there something obvious that I'm missing? Or is there another approach that can be recommended, or should I give up on the django-filter and use the standard django filters and solve the problem as described here: [http://www.ilian.io/django-forms-choicefield-with-dynamic-values/]?
[EDIT]
# Alex Morozov
Yes, my goal is to change the content of the drop down at runtime. In this case, this would involve a new queryset being assigned to the ModelChoiceFilter. Something like this
__init__(self,*args,**kwargs):
self.session = kwargs.pop('session', None)
super(MyFilter,self).__init__(*args, **kwargs)
self.drop_down = ModelChoiceFilter(queryset = MyModel.my_custom_manager.my_customer_filter_that_uses_session(self.session))
I know that this example simply initializes the instance's copy of drop_down (and thus does not have the desired effect), but hopefully the intent is clear?

Python method parameter restricted class

I want to restrict a parameter within a set of options. If the function is called a parameter must be restricted to a couple of options.
This is what I have until now
class GetFileMethod:
URL = 'url'
ATTACHMENT = 'attachment'
class MailClient
def GetFile(self,method)
MailClient.GetFile(GetFileMethod.URL) #works ok, but
MailClient.GetFile("lalala") #should raise an error
Any suggestions?
def GetFile(self, method):
if method not in {'url','attachment'}:
raise ValueError
I would make GetFileMethod a method of the MailClient class and it will make life easier controlling the input.
Change your class MainClient to this:-
you need to check the value of method that you are providing in the namespace of the class GetFileMethod so that :-
GetFileMethod.__dict__.values()
class MailClient:
def GetFile(self, method):
if method in GetFileMethod.__dict__.values():
return 'Yes'
else:
return 'No'

Passing an attribute from method to another method python

Excuse me, I am pretty new to oop in python, but I'm wondering how to pass the value of tld_object in gather_site() to the method gather_path()
class MyClass:
def __init__(self):
print "Class Initialized"
def gather_site(self):
tld_object = Tld.objects.filter(id=3)
return tld_object
def gather_path(self):
path_object = PathsOfDomain.objects.filter(FKtoTld=)
models.py
class Tld(models.Model):
##default table PK here.
##fields here
class PathsOfDomain(models.Model):
##default table PK here.
##fields here
FKtoTld = models.ForeignKey(Tld)
Basically is what is happening in table Tld, has a 1:M relationship to PathsOfDomain and I want to be able to get the related paths, based on tld_object which comes from database in gather_site() method
Any help is graciously appreciated. Thank you.
def gather_path(self):
path_object = PathsOfDomain.objects.filter(FKtoTld=3)
I think should work fine ...
class MyClass:
def __init__(self):
print "Class Initialized"
def gather_site(self, id):
# Note I'm using get instead of filter when dealing with PKs.
# Only one object is going to be returned.
self.tld_object = Tld.objects.get(id=id)
return self.tld_object
def gather_path(self):
# At this point you have to have self.tld_object already set,
# Either check it exists or give it a default value.
path_object = PathsOfDomain.objects.filter(FKtoTld=self.tld_object.id)

Why are form field __init__ methods being called on Django startup?

I have a Django app with custom form fields, some of which have slow operations in their constructors. I was surprised recently to find out that those constructors were getting called when Django itself was starting up, even before a user does something that requires that form in a view.
Why are they getting instantiated at server start?
Example:
urls.py:
from myapp.views import view1
...
url(r'^test$', view1.test),
views/view1.py:
class MyForm(ModelForm):
class Meta:
model = MyModel
field1 = MyChoiceField()
class MyChoiceField(ChoiceField):
def __init__(self, choices=(), required=True, widget=None, label=None,
initial=None, help_text=None, *args, **kwargs):
super(ChoiceField, self).__init__(required, widget, label, initial,
help_text, *args, **kwargs)
self.choices = [(m.id, m.name) for m in ReallyLargeTableModel.objects.all()]
If I set a break point inside that field constructor, then start up Django, it breaks the first time I request any page, even if the view in question does not need that form or field. The stacktrace leads back to the import line in urls.py.
Is this because I'm importing view1 in urls.py, instead of importing view1.test?
Edit: This isn't Django specific, here is a test case the illustrates the behavior:
class Something():
def __init__(self):
print "Something __init__() called"
class UsesSomething():
field = Something()
If you run this in the interactive terminal, it will print "Something init() called". This was surprising to me because I have not actually instantiated a UsesSomething object.
Because you instantiate the fields in the form definition, which is presumably being imported by one of your views.
The field init is the wrong place to do this sort of dynamic initialization, for this exact reason. You want something that is called when the form is initialized: ie, the form's __init__.
That said, you don't actually want to do this at all - you just need to use forms.ModelChoiceField, which takes a queryset and does the dynamic assignment of choices for you.
class MyForm(ModelForm):
field1 = forms.ModelChoiceField(queryset=ReallyLargeTableModel.objects.all())
In your example:
class UsesSomething():
field = Something()
The line of code field = Something() will execute when you import the containing module as Python processes the class definition. This is just how Python works. You can actually put arbitrary code inside a class definition.
module: test.py:
class UsesSomething():
print "wow!"
>>> import test
wow!

Categories

Resources