Cannot Overriding Class HttpRequest Method dispatch in web module? - python

Iam trying to override a method inside web=>http.py file in openerp project .
I have write this code :
#in my_http.py
from openerp.addons import web
class my_httprequest(web.http.HttpRequest):
def dispatch(self, method):
#some new code here ...
but will not overriding the original ?
where is the problem , why cannot override ?

Did you put the 'my_http.py' statement in 'openerp.py' file ?

Related

Define & Use Custom renderer Django Rest Framework View

I'm trying to override a CSV renderer import for a django rest framework view. Here's how so:
class CustomCSVRenderer(BaseCSVRenderer):
def render():
do something
def tablize():
do something
I've defined the CustomCSVRenderer in the same python class views.py as the view in question:
class MyView(ListAPIView, CustomMixinSet):
renderer_classes = (CustomRenderer, JSONRenderer)
When I try to debug this implementation, my pdb debugger never hits the CustomCSVRenderer and instead I get a response based on some underlying renderer used by django restframework.
What could be the issue? How do I know what renderer django rest framework is using?
As #Daniel Roseman stated in the comment section, you'll need to do a little bit more in order to make this custom renderer work.
From the docs:
To implement a custom renderer, you should override BaseRenderer, set the .media_type and .format properties, and implement the .render(self, data, media_type=None, renderer_context=None) method.
Thus, your CustomCSVRenderer should look like this:
class CustomCSVRenderer(BaseCSVRenderer):
media_type = 'text/csv'
format = 'csv'
def render(self, data, media_type=None, renderer_context=None):
...

Import Django class from view to another file

Good afternoon everybody,
I'm fighting with my custom class defined in my Django view in order to use it inside another python file which let me to manage my Menu.
This class is pretty simple, but she uses a custom middleware too:
# main.views.py file
class MyClass:
def my_main_function(self, request):
my_queryset = myModel.objects.filter(application=request.cur_app, display=True).order_by('order')
return my_queryset
def toto(self):
list_test = self.my_main_function()
return list_test
request.cur_app corresponds to my middleware defined in middleware.py file.
I created toto() because I would like to use my_main_function inside another file called menus.py which doesn't handle request.
In this file, I have:
from .views.main import MyClass
for element in MyClass.toto():
... do something ...
But this is the issue encountered:
toto() missing 1 required positional argument: 'self'
I'm conscient there is a possibility of huge issues in my code, because I'm learning programmation at the same time. Be indulgent.

Django 2.1.7 How to use a decorator on a package view

I would like to know how to use a decorator on a function view.py which do not find it directly in my application, but in a pakage (venv / lib / ...)
For more details, I'm going to build an application that uses django-allauth.
I create a decorator that asks the user to confirm their password before accessing certain page.
All goes well but I would like to use this constructor on the function of aullauth that can manage emails.
I do not know how to proceed...
enter image description here
Sorry for my english.
Hi #Pedro So here I have tried the solution for Class Base Views, but it did not work.
As my knowledge is limited I probably did not target the right class ...
Nevertheless, I solved the problem by targeting the url and using the decorator on the targeted url
Here's what it looks like if it can help other people:
...
from allauth.account import views as allauth_views
from .decorators import confirm_password
urlpatterns = [
re_path(r'^accounts/', include('allauth.urls')),
re_path(r"^email/$", confirm_password(allauth_views.email), name="account_email"),
...
]
Thank you very much, I am grateful for your help and time.
It is very likely that your solutions will help me in the future. :)
If it is a fucntion view you can do this
import package_view...
#decorator
def custom_view(request, *args, **kwargs):
return package_view(request, *args, **kwargs)
If it is a CBV you can inherit from it and add a decorator to the dispatch method:
class CustomView(PackageView):
#decorator
def dispatch(request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)

inject library dependencies into django model

I have a Django model that makes use of some libraries which I would like to be able to override. For instance, when testing I'd like to pass a mock instead of having my model tightly coupled. I can do this in python, but for the life of me I can't figure out how to do it with a Django model. Here's a simplified example not using Django:
import requests
class APIClient:
def __init__(self, **kwargs):
self.http_lib = kwargs.get("http_lib", requests)
def get_url(self, url):
return self.http_lib.get(url)
For regular use of this class I can still use requests but if I want to use a different library for some reason or if I want to test certain outcomes, I can invoke the class with client = APIClient(http_lib=MockRequests())
But how do I do that with a Django model? If I try to pass kwargs that aren't backed by a database field Django throws an error. Overriding __init__ is not considered a good practice either. Is there a way in Django to set and get a value that isn't backed by a database column?
Do you have a settings.TEST var? If so, you could make http_lib a function that returns the proper lib:
from django.conf import settings
def get_http_lib(mock=None):
if not mock:
return requests
return MockRequests()
class APIClient(Model):
def __init__(self, **kwargs):
# ...whatever...
#property
def some_column(self):
http_lib = get_http_lib(settings.TEST)
# ...etc...
Not ideal, but passable.
PRE-EDIT ANSWER (doesn't work):
What if you setattr subsequent to instantiating the Model?
# In model...
class APIClient(Model):
def __init__(self, **kwargs):
self.http_lib = requests
# ...etc...
# In tests...
client = APIClient()
setattr(client, 'http_lib', MockRequests())

Permission class on #detail_route not working, Django Rest Framework

I'm new to DRF, but I'm trying to use a permission class on a #detail_route using the method in this stack thread: Using a permission class on a detail route
My code currently looks like this :
#detail_route(methods=['GET'], permission_classes=[IsStaffOrRestaurantUser])
def restaurant_dishes_ready_for_pickup(self, request, pk=None):
...stuff....
class IsStaffOrRestaurantUser(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
print(request)
print(view)
print(obj)
return False
The print statements never get executed... I'm probably missing something but I've looked through the documentation and can't really figure it out, is my approach right at all? Thanks!
EDIT:
I realize in our code already that we have this snippet in our Viewset, is it possible to override this in the decorator?
def get_permissions(self):
# Limit to listing and getting for non Admin user
if self.request.method in permissions.SAFE_METHODS:
return (permissions.AllowAny(),)
return (IsAdminUser(),)
Not sure if it's the most elegant solution, but you might be able to upgrade get_permissions() like so:
def get_permissions(self):
# check additional route specifics
path = self.request.path
if ("restaurant_dishes_ready_for_pickup" in path):
return (IsStaffOrRestaurantUser,)
# Limit to listing and getting for non Admin user
if (self.request.method in permissions.SAFE_METHODS):
return (permissions.AllowAny,)
return (IsAdminUser,)
PS: Also maybe return permission class objects instead of instances in get_permissions().
Quote from the documentation:
If you're writing your own views and want to enforce object level permissions, or if you override the get_object method on a generic view, then you'll need to explicitly call the .check_object_permissions(request, obj) method on the view at the point at which you've retrieved the object.
So you'll need to call explicitly the permission check.
Note that you could have that for free if you were using a RetrieveAPIView instead of a function based view for example.

Categories