auth is not available in module - python

I have a web2py application where I have written various modules which hold business logic and database related stuff. In one of the files I am trying to access auth.settings.table_user_name but it doesn't work and throws and error as global name 'auth' is not defined. If I write the same line in controller, it works. But I want it to be accessed in module file. Please suggest how do I do that.

In your model file, where you define auth:
from gluon import current
auth = Auth(db)
current.auth = auth
Then in a module:
from gluon import current
def some_function():
auth = current.auth
....
For more details, see http://web2py.com/books/default/chapter/29/04/the-core#Accessing-the-API-from-Python-modules.

I was getting a very similar error ("name 'auth' is not defined"). Had to add from django.contrib import auth at the top of views.py and it worked.

Related

Is there a way to move `import` statement to the top of Flask view file when service class references `current_app`?

I am trying to use a global configuration when defining an ElasticSearch DSL model, which is more or less a regular Python class aka service class.
"""Define models"""
from elasticsearch_dsl import Document, Text
from flask import current_app
class Greeting(Document):
"""Define Greeting model"""
message = Text()
class Index:
name = current_app.config['GREETINGS_INDEX']
def save(self, ** kwargs):
return super().save(** kwargs)
Unfortunately, if my import statement is at the top of the view file, I get this error message:
RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context(). See the
documentation for more information.
The only way to get things to work is if I import the model/service class inside the request like this:
from elasticsearch_dsl import Search
from flask import Blueprint, current_app
# from .models import Greeting ### this will throw the application context error
greetings = Blueprint(
'greetings',
__name__,
url_prefix='/greetings/'
)
...
#greetings.route("/elasticsearch/new/")
def new_greeting_using_elasticsearch():
from .models import Greeting ### this avoids the application context error
Greeting.init()
greeting = Greeting(message="hello, elastic")
greeting.save()
return(
"a greeting was saved; "
"it is viewable from https://localhost:5000/greetings/elasticsearch/"
)
This seems like a code smell. Is there another way to accomplish using reusing configurations that can keep the import statement at the top of the file?
These questions/answers seem to suggest that this is the only way:
How to access config value outside view function in flask
Flask - RuntimeError: Working outside of application context
Am I missing something? Should I rearchitect my application to avoid this? Or is this just a Flask-way/thing?
Thank you for your help 🙏
Other questions/answers/articles that did not help me:
"RuntimeError: Working outside of application context " with Python Flask app ( Sending gmail using scheduler )
https://flask.palletsprojects.com/en/0.12.x/appcontext/#creating-an-application-context
Access config values in Flask from other files
RuntimeError: working outside of application context
Python #property in Flask configs?
Reading properties from config file with Flask and Python

Why isn't django.contrib.auth.authenticate() working here?

I'm writing a simple (for now) Django app. I'm having trouble with authentication: I'm trying to use all of the out-of-the-box components, and both in the app itself and in tests, I can't authenticate users. So, for example, here's a test that fails:
from django.conf import settings
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
from django.test import TestCase
[...]
class UserTestCase(TestCase):
def setUp(self):
self.testu = User(username="thename", password="thepassword", first_name="thefirstname")
self.testu.save()
def testAuthenticate(self):
u = authenticate(username="thename", password="thepassword")
self.assertEqual(u.first_name, "thefirstname")
I get an AttributeError:
'NoneType' object has no attribute "first_name".
I think this is because authenticate() is returning None (representing that there is no such user).
This fails whether or not I include the line "self.testu.save()".
I have other tests that pass, so I don't think the problem is with the test infrastructure. I can successfully create users and retrieve their information from the database.
The only mention of User in models.py is:
from django.contrib.auth.models import User
I've read through a lot of documentation but can't figure out what's going on. Can anyone help? Thanks in advance.
You can not create a User object with a password like that. The password needs to be hashed. Therefore, you should use the .set_password(..) method [Django-doc]:
class UserTestCase(TestCase):
def setUp(self):
self.testu = User(username="thename", first_name="thefirstname")
self.testu.set_password("thepassword")
self.testu.save()
# …

How to add the last_login_ip, when the user login if using `rest-auth`?

How to add the last_login_ip, when the user login if using rest-auth?
Befor ask the post I searched one post bellow:
How can I do my logic in `http://127.0.0.1:8000/rest-auth/login/` of `django-rest-auth`?
The answer is perfect for custom verify the login params.
But, how about after login, then add attribute to the User?
I mean, the answer is just for verify the data, I want to after user login success, I want to add the last_login_ip to the user instance.
EDIT
Please be attention, I know how to get the remote IP who visit my site. I mean I use the rest-auth to login, and customized LoginSerializer like the link. The link is for verify the login data, I can not to change the last_login_ip data in the LoginSerializer, I want when the user login success, then change the user's last_login_ip. but where to write my change last_login_ip code?
EDIT-2
I follow the #at14's advice, in the init.py (as the same level as apps.py):
default_app_config = '管理员后台.用户管理.qiyun_admin_usermanage.apps.QiyunAdminUsermanageConfig'
and in the apps.py:
from django.apps import AppConfig
class QiyunAdminUsermanageConfig(AppConfig):
name = 'qiyun_admin_usermanage'
def ready(self):
import 管理员后台.用户管理.qiyun_admin_usermanage.api.signals
There will get bellow error:
django.core.exceptions.ImproperlyConfigured: Cannot import 'qiyun_admin_usermanage'. Check that '管理员后台.用户管理.qiyun_admin_usermanage.apps.QiyunAdminUsermanageConfig.name' is correct.
and I also tried to comment the default_app_config = '管理员后台.用户管理.qiyun_admin_usermanage.apps.QiyunAdminUsermanageConfig' in the init.py, but still not work.
Use django's user logged in signal to save this information into the database.
In signals.py,
from django.contrib.auth.signals import user_logged_in
from django.dispatch import receiver
#receiver(user_logged_in)
def user_logged_in_callback(sender, user, request, **kwargs):
// Get the IP Address and save it
Read more about signals here.
Do pay attention on how to import signals in your app ready method
Make an apps.py (it might already exist) in your app directory,
from django.apps import AppConfig
class YourAppConfig(AppConfig):
name = '管理员后台.用户管理.qiyun_admin_usermanage'
def ready(self):
import 管理员后台.用户管理.qiyun_admin_usermanage.api.signals # noqa
In your apps init.py file,
default_app_config = '管理员后台.用户管理.qiyun_admin_usermanage.apps.QiyunAdminUsermanageConfig'

Execute custom logic after Mezzanine form submission with page_processors.py

I have a question regarding page_processors.py. I've made a contact page with a form through the mezzanine admin and I have some logic that I'd like executed upon completion of that form. After reading the documentation, I found that creating a page_processors.py module in my app should help take care of that, but the file isn't being touched (ie, I can't get to the debugger inside it). Can anyone here help?
Here's my page_processors.py file:
from django import forms
from django.http import HttpResponseRedirect
from mezzanine.pages.page_processors import processor_for
from mezzanine.forms.models import Form
import requests
#do some testing to see that this code is correct
import pdb;pdb.set_trace()
#processor_for(slug="contact")
def form_view(request):
pass
Turns out you shouldn't name your app "site", interferes with an existing module named site (facepalm).

Django Postman Messaging

So i've got django-postman installed in my project. I've got the app installed and the urls are added but it's still not working.
When I try and send a message to the user test for example it's saying "Some usernames are unknown or no more active: test." which makes me think it's trying to use the wrong user model because the username exists in the database, it just can't find it.
I've got these in my settings if it helps.
POSTMAN_DISALLOW_ANONYMOUS = False
POSTMAN_DISALLOW_MULTIRECIPIENTS = False
AUTH_USER_MODEL = 'accounts.User'
Looking at the code for django-postman I have found out the issue. In postman.future_1_5.py it just imports User instead of what I need.
How can I change this code? Is there a way I can keep a file within my application and use that instead?
I'm thinking this will fix my issue:
from __future__ import unicode_literals
from accounts.models import MyUser
MyUser.USERNAME_FIELD = 'username'
MyUser.get_username = lambda self: self.username
def get_user_model():
return MyUser
Modifying future_1_5.py is not the solution to your issue, and is a very bad idea anyway. As its name implies, this file is intended to make the code runnable with Django before version 1.5.
I suppose you're running at least Django 1.5, so if this fallback is fired it means that your custom user model could not be imported.
The right explanation is that your setting is wrong. It has to name the effective model:
AUTH_USER_MODEL = 'accounts.MyUser'

Categories

Resources