Modify static class variable from a different Class/module - python

couldnt find concrete answer to my question in other posts so here it goes :
I need to modify a static class variable from a different class/module. I got my LoginPage class with static variable admin
class LoginPage(BasePage):
#Users
admin = ["testemail1#gmail.com","Password1234!"]
basicUser = ["testemail1#gmail.com", "Password1234!"]
and i got my profile test class which has uses changepassword method/test :
class MyProfileTests(BaseTestCase, LoginPage):
def test_change_password(self):
try:
self.loginAs(self.basicUser)
MyProfilePage(self.driver).changePassword('Password007$$')
and finally changepassword method
def changePassword(self, new_password):
self.driver.find_element_by_xpath(self._change_pw).click()
password_fields = self.driver.find_elements_by_xpath(".//*[#class='form-group']/*/input")
password_fields[1].send_keys(new_password)
self.submit_button.click()
#Changing password for the LoginPage object
self._passwordChange(new_password)
def _passwordChange(self, password):
try:
self.driver.find_element(by=By.XPATH, value = '//*[contains(text(), "Password successfully changed.")]')
LoginPage.admin[1] = password
except NoSuchElementException:
pass
The problem is that it doesn't seem to change actual object which is LoginPage.admin. The idea here is to whenever i use changePassword method that i dont need to manually update the password for the admin/basicuser if i need to login for a differnt test

It seems what i wanted to do is to dynamically modify a line of code in LoginPage.py, which does not work with my code and will probably need some advanced knowledge. I decided to keep all of the logins in a separate .txt file which solved the problem

Related

Auto fill a field in model via function django

I was searching to find a way to fill a field of a model via a function.
example:
def myfunction():
return a_file
class SomeModel(models.Model):
a_field_name=models.FileField(value=my_function())
I some how was thinking to rewrite the save().share with me your idea
Well as per my understanding your question you can try it like this:
def Function(self, parameter: int):
return Models.objects.update_or_create(
variable=parameter
)
Please reply to this message If the issue still persist.

How to access user uid from anywhere in the code?

I'm trying to access the currently logged in user eslewhere in my code (i.e in other classes). I've managed to do this to some extent with global (frowned upon I know but didn't find any other way), as shown below:
class Login(Screen):
def login(self, email, password):
try:
global user
user = auth.sign_in_with_email_and_password(email, password)
print(user['localId']) #This is the users uid
class SelectChat(Screen):
def __init__(self, **kwargs):
super(SelectChat, self).__init__(**kwargs)
grid = GridLayout(cols=1)
self.add_widget(grid)
docs = db.collection(u'users').where(u'value', u'==', True).stream()
for doc in docs: # cycle through database and create Buttons for each value found
dict = doc.to_dict()
btn = Button(text="{} {}".format(dict['first_name'], dict['last_name']), id=doc.id)
btn.bind(on_release=self.move_to_chat(doc.id))
grid.add_widget(btn)
def move_to_chat(self, *args):
group_id = str(user['localId']) + str(doc.id) # This is where I'm trying to access the user variable but it's getting called on startup due to the above ```btn.bind()``` call.
print(group_id)
MDApp.get_running_app().sm.current = "chat"
The problem I'm having now is that I want to access the user['localId'] value in the __init__ method of another class. As this is run when as soon as the app has loaded the login method hasn't started and therefore there's no user variable.
Error message: NameError: name 'user' is not defined

How to attach a python file to each row(i.e. each data entry) in database formed using Django?

Ive used default django superuser to create an admin and created a DB using it. But now in that i want to add a python script to each data entry i.e. row. How do i do this???
Nothing special. Used basic Django.
There doesn't seem to be anything particularly complex here. You're just asking if you can use a field on the model to choose something; of course you can.
For instance:
# actions.py
def thing1(obj):
# do something with obj
def thing2(obj):
# do something else with obj
# models.py
from . import actions
ACTIONS = {
"do_thing_1": actions.thing1,
"do_thing_2": actions.thing2,
}
ACTION_CHOICES = [(action, action) for action in ACTIONS]
class MyModel(models.Model):
action = models.CharField(max_length=20, choices=ACTION_CHOICES)
def do_action(self):
return ACTIONS[self.action](self)

Django related User Model - Permissions and Decorators

i am a beginner to Django i am trying to use permissions to permit access to specific view functions via a decorator, for specific user types only. Right now i am totaly confused by all kinds of stuff i have read about and seam not to figure out how i should do this.
I have two different kinds of users let it be UserTypeONE and UserTypeTWO.
UserTypeONE and UserTypeTWO should have access to specific views only.
Here is my code:
myuserTypes.py
class UserTypeONE(models.Model):
lieOtO_User = models.OneToOneField(settings.AUTH_USER_MODEL)
lie_SomeAttribute= models.CharField(max_length=300, help_text ='Name')
class Meta:
permissions = (('Can_View_MyShop', 'Can see Shop View'),)
class UserTypeTWO(models.Model):
lieOtO_User = models.OneToOneField(settings.AUTH_USER_MODEL)
lie_SomeOtherAttribute= models.CharField(max_length=300, help_text ='Name')
class Meta:
permissions = (('Can_View_Targets', 'Can see the Targets'),)
Here is what i am trying to do in my views.py
#login_required
#permission_required('UserTypeONE.Can_View_MyShop', raise_exception=True)
def MyShopView(request):
#do something
i also tried
#user_passes_test(lambda u: u.usertypeone.permission('Can_View_MyShop'))
As you guys can see i am an absolute beginner unfortunately all documentations and examples havent done me any good instead i am even more confused.
I would really appreciate help on this.
I would use user_passes_test() here since you specifically want to restrict specific views.
First, define a couple of functions that return True when you're dealing with a user who should be able to see your content. It looks like your UserTypeOne and UserTypeTwo models extend the base User model with a one-to-one relationship, so you can use hasattr to check if a given base user has one of those attributes:
def type_one_only(user):
if hasattr (user, 'usertypeone'):
return True
else:
return False
def type_two_only(user):
#same thing without if/else
return hasattr(user, 'usertypetwo')
Now when you have a view that you want to restrict to one user type, you can add a user_passes_test decorator before it:
#user_passes_test(type_one_only, login_url='/')
def my_view(request):
...
login_url is where a user will be sent if they do not pass the test you've indicated.

Django models: Only permit one entry in a model?

I want to make some of my Django global settings configurable through the admin interface.
To that end, I've decided to set them as database fields, rather than in settings.py.
These are the settings I care about:
class ManagementEmail(models.Model):
librarian_email = models.EmailField()
intro_text = models.CharField(max_length=1000)
signoff_text = models.CharField(max_length=1000)
These are one-off global settings, so I only ever want there to be a single librarian_email, intro_text etc floating around the system.
Is there a way I can prevent admin users from adding new records here, without preventing them from editing the existing record?
I guess I can do this by writing a custom admin template for this model, but I'd like to know if there's a neater way to configure this.
Could I use something other than class, for example?
Thanks!
Please see this question on "keep[ing] settings in database", where the answer seems to be django-dbsettings
Update
Just thought of another option: you can create the following model:
from django.contrib.sites.models import Site
class ManagementEmail(models.Model):
site = models.OneToOneField(Site)
librarian_email = models.EmailField()
intro_text = models.CharField(max_length=1000)
signoff_text = models.CharField(max_length=1000)
Because of the OneToOneField field, you can only have one ManagementEmail record per site. Then, just make sure you're using sites and then you can pull the settings thusly:
from django.contrib.sites.models import Site
managementemail = Site.objects.get_current().managementemail
Note that what everyone else is telling you is true; if your goal is to store settings, adding them one by one as fields to a model is not the best implementation. Adding settings over time is going to be a headache: you have to add the field to your model, update the database structure, and modify the code that is calling that setting.
That's why I'd recommend using the django app I mentioned above, since it does exactly what you want -- provide for user-editable settings -- without making you do any extra, unnecessary work.
I think the easiest way you can do this is using has_add_permissions function of the ModelAdmin:
class ContactUsAdmin(admin.ModelAdmin):
form = ContactUsForm
def has_add_permission(self, request):
return False if self.model.objects.count() > 0 else super().has_add_permission(request)
You can set the above to be any number you like, see the django docs.
If you need more granularity than that, and make the class a singleton at the model level, see django-solo. There are many singleton implementations also that I came across.
For StackedInline, you can use max_num = 1.
Try django-constance.
Here are some useful links:
https://github.com/jezdez/django-constance
http://django-constance.readthedocs.org/en/latest/
I'd take a page out of wordpress and create a Model that support settings.
class Settings(models.Model):
option_name = models.CharField(max_length=1000)
option_value = models.CharField(max_length=25000)
option_meta = models.CharField(max_length=1000)
Then you can just pickle (serialize) objects into the fields and you'll be solid.
Build a little api, and you can be as crafty as wordpress and call. AdminOptions.get_option(opt_name)
Then you can just load the custom settings into the runtime, keeping the settings.py module separate, but equal. A good place to write this would be in an __init__.py file.
Just set up an GlobalSettings app or something with a Key and Value field.
You could easily prevent admin users from changing values by not giving them permission to edit the GlobalSettings app.
class GlobalSettingsManager(models.Manager):
def get_setting(self, key):
try:
setting = GlobalSettings.objects.get(key=key)
except:
raise MyExceptionOrWhatever
return setting
class GlobalSettings(models.Model):
key = models.CharField(unique=True, max_length=255)
value = models.CharField(max_length=255)
objects = GlobalSettingsManager()
>>> APP_SETTING = GlobalSettings.objects.get_setting('APP_SETTING')
There are apps for this but I prefer looking at them and writing my own.
You can prevent users from adding/deleting an object by overriding this method on your admin class:
ModelAdmin.has_add_permission(self, request)
ModelAdmin.has_delete_permission(self, request, obj=None)
Modification of #radtek answer to prevent deleting if only one entry is left
class SendgridEmailQuotaAdmin(admin.ModelAdmin):
list_display = ('quota','used')
def has_add_permission(self, request):
return False if self.model.objects.count() > 0 else True
def has_delete_permission(self, request, obj=None):
return False if self.model.objects.count() <= 1 else True
def get_actions(self, request):
actions = super(SendgridEmailQuotaAdmin, self).get_actions(request)
if(self.model.objects.count() <= 1):
del actions['delete_selected']
return actions
I had basically the same problem as the original poster describes, and it's easily fixed by overriding modelAdmin classes. Something similar to this in an admin.py file easily prevents adding a new object but allows editing the current one:
class TitleAdmin(admin.ModelAdmin):
def has_delete_permission(self, request, obj=TestModel.title):
return False
def has_add_permission(self, request):
return False
def has_change_permission(self, request, obj=TestModel.title):
return True
This doesn't prevent a user from posting a form that edits data, but keeps things from happening in the Admin site. Depending on whether or not you feel it's necessary for your needs you can enable deletion and addition of a record with a minimum of coding.

Categories