Add upload file functionality in Django Admin - python

I have seen multiple replies for how to upload a file through Django ADMIN interface
There were two kind of replies:-
A) using django inline classes, as mentioned in link_A and link_B. I followed link_A
But for some reason it did not work for me. So is there something missing in the above links mentioned?
I am not sure what is the purpose of following code block in the link_A:-
def save(self, *args, **kwargs):
if not self.id:
... unzip your file ...
... encrypt your file if necessary ...
super(File, self).save(*args, **kwargs)
Question:- Django admin shall automatically perform a SAVE functionality for you. So, what is the purpose of the above SAVE function when DJANGO ADMIN shall automatically do it for you?
B)using upload file functionality in normal DJango code(Not Django admin). I followed the link. It mentions to write a View that handles a POST request. And using a ModelForm save it and render the view again
What I did:- Added a FileField() button file = models.FileField(storage=fs).
My understanding:- Normal Django code(Not DJANGO Admin), we have to write ModelForms and VIEWS to handle HTTP respnose and request methods. But Django admin hides HTTP response and request functionality from the end user. Somehow it performs handling of HTTP request and HTTP response behind the scene. So me bypassing Django admin and trying to manually capture POST request(just for file upload) as mentioned in the link does not sound right.
From my point of view I just need to add a FileField() button to the DJANGO ADMIN. When i hit the SAVE button DJANGO ADMIN should handle POST request behind the scene as it does for normal model fields.
Question:- Is my understanding of how a file should be uploaded using Django ADMIN interface correct?

Related

Django open an external link passing POST data

In my Django project i need to call from my function into my views.py an external page passing in POST format some data.
i do this:
in urls.py:
...
url(r'^gocard/(?P<lic_num>\w+)/$', go_ccredit),
...
in my views.py i create the function go_ccredit:
def go_ccredit(request, lic_num=None, **kwargs):
requests.post('https://www.example.com/form_test', data={'lid':lic_num,})
but i got an error because no HTTPResponse vas returned, and no page was open.
I need to open an external page because i need to populate some form field with my data (using POST) and some other have to be populated by user.
How can i open from my django function my external page passing data in POST ?
So many thanks in advance

Login-error page not displayed when using python-social-auth

I am using social-app-django (part of python-social-auth) to implement Facebook login for the users of my Django site. I have a requirement that users must be found in the local user database before they can log in with Facebook. I have replaced the auth_allowed-part of the authentication pipeline, to perform this check:
def auth_allowed(backend, details, response, *args, **kwargs):
if not backend.auth_allowed(response, details) or not is_registered_user(response, details):
raise AuthForbidden(backend)
where is_registered_user() is a custom function that checks whether the user exists locally.
My problem is that the users are not redirected to the login error URL, if this check fails and the AuthForbidden exception is thrown. Instead, the site returns a 500.
The error-page URL is configured as follows in settings.py:
LOGIN_ERROR_URL = "/"
I am using Django CMS, so I have also tried implementing middleware that overwrites SocialAuthExceptionMiddleware (which is supposed to handle the AuthForbidden exception in a standard setup) to return a CMS-page instead of an URL from settings.py but this middleware is not invoked in the process, as far as I can see.
Any ideas on how to fix this? Am I missing some configuration?
I think I solved the problem: I accidentally used
social.apps.django_app.middleware.SocialAuthExceptionMiddleware
instead of
social_django.middleware.SocialAuthExceptionMiddleware
when referring to the exception-handling middleware. The bug was most likely introduced during an upgrade from django-social-auth to python-social-auth/social-app-django some time ago.

Django: Display website name in Template/Emails without using Sites framework

I want to render my website name in django templates. Django's own docs on Sites state:
Use it if your single Django installation powers more than one site
and you need to differentiate between those sites in some way.
My django app doesn't. I know I can still use it, but it seems like an overkill. I just want to pull a variable with my website's name (!= domain) in ANY template. I don't want to pass it in views either because that doesn't seem DRY enough.
Writing a custom processor seemed like a simple-enough option, but for some reason these variables aren't available in the .txt emails django-registration sends (while other variables definitely are, so I guess it's not impossible).
TIA
Edit: was asked to include code that doesn't work:
processors.py:
def get_website_name(request):
website_name = 'SomeWebsite'
return {'mysite_name': website_name}
Included successfully in context_processors in settings.py. It works nicely in "regular" templates, but not in emails.
Here's how I'm sending the emails, inside a change_email_view:
msg_plain = render_to_string('email_change_email.txt', context)
msg_html = render_to_string('email_change_email.html', context)
send_mail(
'Email change request',
msg_plain,
'my#email',
[profile.pending_email],
html_message=msg_html,
)
A further problem is that django-regitration further abstracts some of those views away: so when a user registers, wants to reset a password, etc...I don't even have access to the views.
Based on Django custom context_processors in render_to_string method you should pass the request to render_to_string.
msg_plain = render_to_string('email_change_email.txt', context, request=request)
msg_html = render_to_string('email_change_email.html', context, request=request)

Require new login for each page view

I am currently using code found here:
http://flask.pocoo.org/snippets/8/
And I decorate my function accordingly to have the admin authenticate when requesting a specific admin page. However, instead of requiring the admin to keep authenticating each time they admin page, I noticed that it somehow keeps track of the session and no longer requires authentication after successfully authenticating once. Is there some way to force flask to re-authenticate every time an admin requests the given decorated admin page?
Using the included snippet, there is no good way to force a user to log in every time they request the given page.
This is because that snippet is using HTTP Basic Auth and there is no good way to ask the browser to stop sending that header.
What you are looking for can be done with a custom decorator. You can use the sample below. Note that your case will be different, but you can use this as a guide.
from web import app, has_role
#app.route("/admin/my_page")
#login_required
#has_role(role="admin")
def admin_my_page():
//do stuff
Then, in your project init, or an include file you can add the following:
def has_role(role=None):
def _initial_decorator(view_func):
def _decorator(*args, **kwargs):
response = view_func(*args, **kwargs)
if g.user.user_level != role:
from flask import redirect, url_for
return redirect(url_for("no_access"))
return response
return wraps(view_func)(_decorator)
return _initial_decorator
This should at lease give you an idea of how to create a custom decorator, and then check for role permissions. You can expand this to however you need. You can put engine logic, or other checks to fit your project.

Render Django view in new window

I have a Django view that I want to render in a new window when it is called from a python script outside of views.py. My questions are 1.Can I use a Django view from a python script in a subdirectory of my project that is outside the app where the view is located (view location: MyProject/Myapp/views.py and the python script location: MyProject/ProcessingCode/myscript.py)? 2. If that is possible, how do I render the view in a new window?
Django view that I want rendered in a new window:
def Error_Popup_Page(request,message):
context = {'message':message}
return render(request,'InterfaceApp/Error_Notification.html',context)
How it will be used:
def SomeOtherPythonFunction():
try:
#data processing code
except Exception as e:
return Error_Popup_Page(request,'error message')
You're trying to trigger a change on the user browser from on an event that happens on your server. This is impossible to do with Django alone, since Django job is only to respond user requests.
This is where Django is placed in the request chain:
User browser (click on href or ajax event) --> Your server --> Django
--> User browser (gets response and display to the user)
As you can see, there is no way for Django to trigger any event on the user end without the user calling it.
What you're trying to do can be achieved with an async task: in other words, you have to open a websocket and connect the user browser to it with JavaScript.
There are many frameworks for doing this, Celery being the most used in conjuction with Django.
nodejs is also widely used but integrating it with Django is more complex.

Categories

Resources