How to retrieve URL fragment parameters in drf APIView? - python

I have created a callback view for instagram account connection in django by inheriting the APIView class.
After successful connection of instagram account facebook redirects me to the InstagramConnectCallbackView and includes the response data as a URL fragment.
url:
http://localhost:8000/v1/instagram-connect/callback/?#access_token=EAAN....&data_access_expiration_time=1650543346&expires_in=6254&state=eyd...
But I don't know how to read the URL fragments from the request into the get method.
callback view:
class InstagramConnectCallbackView(APIView):
permission_classes = (permissions.AllowAny,)
version = settings.FACEBOOK_GRAPH_API_VERSION
def get(self, request, format=None):
....
I tried the following:
request.get_full_path() # returns `/v1/instagram-connect/callback/`
request.query_params() # returns `{}`
Any help will be appreciated.

You can use query_params as
request.query_params.get('your_key_name')
If you want default then yot can use
self.request.query_params.get('your_key_name', None)
In your case you can get values like
access_token = self.request.query_params.get('access_token', None)
data_access_expiration_time = self.request.query_params.get('data_access_expiration_time', None)
expires_in = self.request.query_params.get('expires_in', None)
and so on ...

Related

Headers not visible in ModelAdmin get_form()

My model is such that each website has an associated email address. An administrator would select a set of websites on the website list view and use an admin action to pass the email addresses of the selected websites to recipient field of a new email_message object. From here, the administrator should be able to customize an email that is sent to each of those email addresses.
The problem is that I can't pass headers to the get_form() method in the new email_message view. When I run the code, the print function that you see included here prints <QueryDict: {}>.
How can I pass header data from an admin action to another model's get_form method?
admin.py:
def email_selected(modeladmin, request, queryset):
response = HttpResponseRedirect('/admin/websites/email_message/add/')
response['queryset'] = queryset
return response
class WebsiteAdmin(admin.ModelAdmin):
actions = [email_selected]
class Email_messageAdmin(admin.ModelAdmin):
def get_form(self, request, obj, **kwargs):
print(request.GET)
form = super(Email_messageAdmin, self).get_form(request, obj, **kwargs)
return form
Thank you in advance for your time.

Passing a header value to a get request in django

I want to pass a value through the Headers of a get request.
Im trying the below but it doesn't work,
class ListCategoriesView(generics.ListAPIView):
"""
Provides a get method handler.
"""
serializer_class = CategorySerializer
def get(self, request, *args, **kwargs):
token = request.data.get("token", "")
if not token:
"""
do some action here
"""
if not UserAccess.objects.filter(accessToken=token).exists():
"""
do some action here
"""
else:
"""
do some action here
"""
I want to pass the token in the headers like that :
can anyone help me with this issue,
thanks a lot in advance.
You said it yourself, you're passing it in the headers, so you need to get it from there. DRF does not do anything special to access the headers, so it proxies to the underlying Django HttpRequest object, which makes them available via the META attribute, converted to uppercase and prefixed by HTTP_:
token = request.META.get("HTTP_TOKEN", "")

How to send POST request to Django REST API using python requests

I have a simple rest api which I want to send a post request to using requests.
My url pattern is this:
url(r'^$', views.ProductList.as_view())
Inside my view I have:
class ProductList(generics.ListAPIView):
serializer_class = ProductSerializer
def post(self, request, format=None):
print('THIS IS A POST REQUEST')
queryset = [product.name for product in Product.objects.all()]
return Response(queryset)
And I am trying to send a post request using:
response = requests.post('http://127.0.0.1:8080/')
However this returns a 403, and the print statement isn't printed. I have done some research and I think it may have something to do with the CSRF token not being there but i'm not to sure how to add that. Does anybody know how I can get the post request to work?
I'm using python 3.6.3 and Django 1.10
ListAPIView is meant for only listing your products hence the POST requests are forbidden.
ListAPIView
Used for read-only endpoints to represent a collection of model instances.
taken from Django Rest Framework documentation
You should use ListCreateAPIView:
class ProductList(generics.ListCreateAPIView):
"""
List all products or create a product.
"""
queryset = Product.objects.all()
serializer_class = ProductSerializer

get user with token django rest framework

sorry for my english. It is not good.
I work with rest framework django. I want to recover a user with his token. This Token must be sent via a post request
class GetUser(generics.ListCreateAPIView):
serializer_class = serializers.UserBasicSerializer
def get_queryset(self):
return models.Member.objects.filter()
def post(self, request, *args, **kwargs):
user = Token.objects.get(*args, **kwargs).user
i receive this error message
rest_framework.authtoken.models.MultipleObjectsReturned: get() returned more than one Token -- it returned 2!
thanks
Use:
user = Token.objects.filter(*args, **kwargs)
if user.exists():
user = user.last().user
The answer to your question is in the docs. Take a look here: http://www.django-rest-framework.org/api-guide/requests/#user
Basically, you just need to get from request the method user. For example:
def api_name_of_api(request):
user_data = request.user # Get username
user_data = request.user.id # Get user id
...

How to test that a view is only accessed by staff users in Django

I am learning testing in Django, and have a view which I want to test. This view should only be accessed by staff users. Suppose the view is:
def staff_users(request):
....
# some logic
return HttpResponseRedirect('/repositories/')
if the request is coming from staff users, it should redirect to repositories otherwise I should get something like permission denied. I am starting with something like in tests.py.
def test_request_object(self):
self.user = User.objects.create_user(
username='abc', email='abc#gmail.com', password='1234')
request = HttpRequest()
# User send a request to access repositories
response = staff_users(request)
self.assertIsNone(response)
The problem is here I am not associating my request object with any users, and I also got to know about from django.contrib.admin.views.decorators import staff_member_required but not sure how to use them here. Could anyone tell me how should I test my view should only be accessed by staff users?
All you need to do is decorate your view which you want to protect as shown below:
#staff_member_required
def staff_users(request):
....
# some logic
return HttpResponseRedirect('/repositories/')
If you want a custom logic for testing instead of using django decorator then you can write your own decorator as well.
def staff_users_only(function):
def wrap(request, *args, **kwargs):
profile = request.session['user_profile']
if profile is True: #then its a staff member
return function(request, *args, **kwargs)
else:
return HttpResponseRedirect('/')
wrap.__doc__=function.__doc__
wrap.__name__=function.__name__
return wrap
and use it as:
#staff_users_only
def staff_users(request):
....
# some logic
return HttpResponseRedirect('/repositories/')
Edit
Association of sessions on request object for testing can be done as:
def test_request_object(self):
self.user = User.objects.create_user(
username='abc', email='abc#gmail.com', password='1234')
request = HttpRequest()
#create a session which will hold the user profile that will be used in by our custom decorator
request.session = {} #Session middleware is not available in UnitTest hence create a blank dictionary for testing purpose
request.session['user_profile'] = self.user.is_staff #assuming its django user.
# User send a request to access repositories
response = staff_users(request)
#Check the response type for appropriate action
self.assertIsNone(response)
Edit 2
Also it would be a far better idea to use django Client library for testing:
>>> from django.test import Client
>>> c = Client()
>>> response = c.post('/login/', {'username': 'abc', 'password': '1234'})
>>> response.status_code
200
>>> response = c.get('/user/protected-page/')
>>> response.content
b'<!DOCTYPE html...

Categories

Resources