UnboundLocalError:local variabel 'socialhandle' referenced before assignment - python

I'm working on a django project and i'm trying to fetch data from the database, according to some primary key value. However when the object exists in the DB then everything is working fine but when it doesn't then django is raising:
UnboundLocalError: local variable 'socialhandle' referenced before assignment.
Here is my django view:
def profile(request, profile_id):
"""View for returning a unique profile"""
profile = get_object_or_404(UserProfile, pk=profile_id)
try:
socialhandle = SocialPlatform.objects.get(user_id=profile_id)
except socialhandle.DoesNotExist:
socialhandle = None
context = {
'profile' : profile,
'socialhandle' : socialhandle,
}
return render(request, 'profiles/profile.html', context)

You cannot access socialhandle.DoesNotExist in the except block because if the try does not interpret successfully, socialhandle would still be undefined.
Solution 1: Use Django's standard exception for this case:
from django.core.exceptions import ObjectDoesNotExist
...
try:
socialhandle = SocialPlatform.objects.get(user_id=profile_id)
except ObjectDoesNotExist:
socialhandle = None
Solution 2: Look at the answer of #JPG

The proper way of handling the DoesNotExist is,
try:
...
except SomeModel.DoesNotExist:
...
Where the SomeModel should be the model class, not the model "instance"
So,
use except SocialPlatform.DoesNotExist instead of except socialhandle.DoesNotExist
def profile(request, profile_id):
"""View for returning a unique profile"""
profile = get_object_or_404(UserProfile, pk=profile_id)
try:
socialhandle = SocialPlatform.objects.get(user_id=profile_id)
except SocialPlatform.DoesNotExist:
socialhandle = None
context = {
'profile' : profile,
'socialhandle' : socialhandle,
}
return render(request, 'profiles/profile.html', context)

Related

I want to get only customer id but getting whole customer information

I am trying to show orders by customer id by i am getting this error :
TypeError at /orders
Field 'id' expected a number but got {'id': 3, 'phone_number': '01622153196', 'email': 'sakibovi#gmail.com', 'password': 'pbkdf2_sha256$216000$H2o5Do81kxI0$2tmMwSnSJHBVBTU9tQ8/tkN7h1ZQpRKrTAKkax1xp2Y=', 'coin': 1200.0}.
Actually i want to fetc only customer id but getting whole dictionary.
Here in Login Class in views.py i fetch whole customers info like this
request.session['customer'] = customer.__dict__
Here is the details :
class Login(View):
def get(self, request):
return render(request, 'signupsignin/signin.html')
def post(self, request):
phone_number = request.POST.get('phone_number')
password = request.POST.get('password')
customer = Customer.get_customer(phone_number)
error_message = None
if customer:
match = check_password(password, customer.password)
if match:
customer.__dict__.pop('_state')
request.session['customer'] = customer.__dict__
# request.session['customer'] = customer.id
#request.session['customer'] = customer.coin
#request.session['phone_number'] = customer.phone_number
return redirect('Home')
else:
error_message = 'Phone number or Password didnt match on our record'
else:
error_message = 'No Customer Found! Please Registrer First!'
print(phone_number, password)
context = {'error_message':error_message}
return render(request, 'signupsignin/signin.html', context)
I think for that reason i am getting the whole informaton of a customer
Here is my Views.py for userorders by customer id ::
class UserOrders(View):
def get(self, request):
customer = request.session.get('customer')
user_orders = Order.get_orders_by_customer(customer)
print(user_orders)
args = {'user_orders':user_orders}
return render(self.request, 'Home/all_orders.html', args)
Here i have a method named get_orders_by_customer() i made this in models.py
Here it is ::
#staticmethod
def get_orders_by_customer(customer__id):
return Order.objects.filter(customer=customer__id)
So what i am trying to do is customers can see their own orders.I have a panel called "all orders" here a customer can see their own order only.
Please Help me i got really confused here
As per my understanding, you have to pass a number, but you're passing a whole dictionary.
#staticmethod
def get_orders_by_customer(customer__id):
return Order.objects.filter(customer=customer__id)
here before return try to debug with a print or something. and you'll see what I mean.
try this and it should work, if im not wrong:
costomer__id['id'] instead of costomer__id
or change your code into this:
#staticmethod
def get_orders_by_customer(customer):
return Order.objects.filter(customer=customer['id'])
You can try using values() query to achieve your purpose.
Here is the link to the documentation - https://docs.djangoproject.com/en/3.1/ref/models/querysets/#values

How to reuse a function or class in Django

This is my class TimesheetListApiV2 there are lots of such kind of classes.
#valid_accesstoken_check
class TimesheetListApiV2(APIView):
def get(self, request):
try:
accesstoken=AccessToken.objects.get(
token=self.request.META.get('HTTP_AUTHORIZATION').replace('Bearer ', '')
)
except ObjectDoesNotExist:
return Response (
{
"status" : False,
"error" : "Wrong Access Token",
"error_message":"You have provided wrong access token.",
}
)
Now in all my classes this piece of code is there.
try:
accesstoken=AccessToken.objects.get(
token=self.request.META.get('HTTP_AUTHORIZATION').replace('Bearer ', '')
)
except ObjectDoesNotExist:
return Response (
{
"status" : False,
"error" : "Wrong Access Token",
"error_message":"You have provided wrong access token.",
}
)
I want to write a function or class where to reuse that code instead of writing it. But it should be workable even request should be pass. Even in future i am going to add more such code which should be reused.
I tried to make this decorators.py
from django.core.exceptions import ObjectDoesNotExist
from oauth2_provider.models import AccessToken
def valid_accesstoken_check(function):
def wrap(request, *args, **kwargs):
try:
accesstoken=AccessToken.objects.get(
token=self.request.META.get('HTTP_AUTHORIZATION').replace('Bearer ', '')
)
except ObjectDoesNotExist:
return Response (
{
"status" : False,
"error" : "Wrong Access Token",
"error_message":"You have provided wrong access token.",
}
)
wrap.__doc__ = function.__doc__
wrap.__name__ = function.__name__
return wrap
But it is giving error
path('timesheet/list', views.TimesheetListApiV2.as_view(), name='api_v2_timesheet_list'),
AttributeError: 'function' object has no attribute 'as_view'
Your decorator should apply to the get method, not the class itself:
class TimesheetListApiV2(APIView):
#valid_accesstoken_check
def get(self, request):
...

Django queryset with variable value

I am writing dynamic filters in django for my database where I am using the below code where I have 2 variables(p_type,s_type):
p_type=[]
s_type=[]
query = request.GET.get("q")
p_type =request.GET.get("p_type")
s_type = request.GET.get("s_type")
#messages.add_message(request, messages.INFO, p_type)
#messages.add_message(request, messages.INFO, s_type)
if query:
queryset_find = queryset_list.filter(
Q(FP_Item__contains=query))
context = {'object_list': queryset_find}
return render(request, 'index.html', context)
elif p_type:
queryset_find = queryset_list.filter(
Q(p_type__contains=s_type))
context = {'object_list': queryset_find}
return render(request, 'index.html', context)
else:
context = {'object_list': queryset}
return render(request, 'index.html', context)
but django returns error at below line
Q(p_type__contains=s_type))
I have dynamic radio button where the value of p_type matches with my database but even though I am receiving the following error:
Exception Type: FieldError
Exception Value:
Cannot resolve keyword 'p_type' into field. Choices are: ... (same choices which I am using with my database).
Isn't it doable with variable query ? Any other methods ?
model:
class RFP(models.Model):
FP_Item = models.TextField(max_length=1500)
P_63 = models.TextField(max_length=1000)
P_64 = models.TextField(max_length=1000)
If p_type holds the name of the field you want to query, then you can do:
elif p_type:
kwargs = {
'{}__contains'.format(p_type): s_type
}
queryset_find = queryset_list.filter(Q(**kwargs))
...

Django multiple forms on one view

I have a Django template that has data from a few different model types combining to make it. A dashboard if you will. And each of those has an edit form.
Is it best to process all those forms in one view as they are posted back to the same place and differentiating between them by a unique field like below?
Or if having lots of different dedicated avenues is the way forward? Thanks for any guidance
class ProjectDetail(DetailView):
template_name = 'project/view.html'
def get_object(self):
try:
return Project.objects.filter(brief__slug=self.kwargs['slug']).filter(team=get_user_team(self.request)).first()
# add loop to allow multiple teams to work on the same brief (project)
except Exception as e:
project_error = '%s (%s)' % (e.message, type(e))
messages.error(self.request, 'OH NO! %s' % project_error)
return redirect('home')
def get_context_data(self, **kwargs):
project = self.get_object()
context = dict()
context['project'] = project
context['milestone_form'] = MilestoneForm(initial={'project': project})
context['view'] = self
return context
def post(self, request, *args, **kwargs):
# get the context for the page
context = self.get_context_data()
try:
# switch for each of the form types on the team profile page (shown if member)
if 'milestone_form_submit' in request.POST:
project=self.get_object()
# set date arbitrarily to half way to brief deadline
brief = Brief.objects.get(project=project)
last_milestone = self.milestones().last()
milestone_del_date = last_milestone.del_date + timedelta(days=7)
new_milestone = Milestone(
project=project,
title_text=request.POST.get('title_text'),
del_date=milestone_del_date,
)
try:
new_milestone.save()
messages.success(self.request, "Excellent! New delivery popped on the bottom of the list")
except Exception as e:
# pass the erroring form back in the context if not
form = MilestoneForm(request.POST)
context['milestone_form'] = form
messages.error(self.request, "OH NO! Deadline didn't save. Be a sport and check what you entered")
elif 'milestone-edit-date-form-submit' in request.POST:
# get object from db
milestone = Milestone.objects.get(pk=request.POST['id'])
# update del_date field sent
milestone.del_date = request.POST['del_date']
# save back to db
milestone.save()
messages.success(self.request, "Updated that delivery right there!")
elif ...
except Exception as e:
messages.error(self.request, "OH NO! Deadline didn't save. Be a sport and check what you entered")
return render(request, self.template_name, context)
You can use mixins in order to solve your problem.
Example from the gist https://gist.github.com/michelts/1029336
class MultipleFormsMixin(FormMixin):
"""
A mixin that provides a way to show and handle several forms in a
request.
"""
form_classes = {} # set the form classes as a mapping
def get_form_classes(self):
return self.form_classes
def get_forms(self, form_classes):
return dict([(key, klass(**self.get_form_kwargs())) \
for key, klass in form_classes.items()])
def forms_valid(self, forms):
return super(MultipleFormsMixin, self).form_valid(forms)
def forms_invalid(self, forms):
return self.render_to_response(self.get_context_data(forms=forms))
As you can see, when you inherit from this class, you can handle multiple forms simultaneously. Look at the gist's code and adapt it to your problem.
Look at this answer

return response in django rest-framework

I am writing an app in django rest-framework:
My views.py:
class tagList(generics.ListCreateAPIView,APIView):
model = tags
serializer_class = getAllTagsDetailSerializer
def get_queryset(self):
print "q1"
print self.request.QUERY_PARAMS.get('tag', None)
print self.request.user
print "q1"
if tags.objects.filter(tag='burger')!= None:
return tags.objects.filter(tag='burger')
else:
content = {'please move along': 'nothing to see here'}
return Response(content, status=status.HTTP_404_NOT_FOUND)
I want to return error status code if query returns None.
But the problem if i try to set Response it throws error:
Exception Type: TypeError
Exception Value:
object of type 'Response' has no len()
Exception Location: /usr/local/lib/python2.7/dist-packages/django/core/paginator.py in _get_count, line 53
Else if query result is Not None it is working.
How can i set status code on Django rest-framework.
The method is expected to return a QuerySet, not a Response object, my bet is that you should throw an Exception, either an APIException or an Http404.
Anyway your handling seems odd, I think you should just return the QuerySet and the framework will handle if the result is empty or not. The method should look like this:
def get_queryset(self):
return tags.objects.filter(tag='burger')
Can you try this
model = tags # Model name
serializer_class = getAllTagsDetailSerializer # Call serializer
def get_queryset(self):
key = self.request.QUERY_PARAMS.get('appKey', None)
getTagName = self.request.QUERY_PARAMS.get('tagName')
keyData = app.objects.filter(appKey=key).exists()
try:
if keyData == True:
return tags.objects.filter(tag=getTagName)
else:
raise exceptions.PermissionDenied
except app.DoesNotExist:
pass
I think it will work....

Categories

Resources