Getting a value from request, django - python

I am trying to get a value from request and really suprised an error is being raised.
def product_view(request):
lookup_type_user = request.GET.get('lookup_type', '')
LOOKUP_TYPE_CHOICES = (
('gt', '>'),
('lt', '<'),
)
class ProductFilter(django_filters.FilterSet):
lookup_type = django_filters.ChoiceFilter(choices=LOOKUP_TYPE_CHOICES)
price = django_filters.NumberFilter(lookup_type=lookup_type_user)
This line, being basically the same, works fine.
price = django_filters.NumberFilter(lookup_type='gte')
I am not posting the error message because it's a package relevant one and since the line above where I provided lookup_type by hand did not raise anything I am assumming it has nothing to do with that package but the code above.
Can you see what goes wrong here?
#EDIT
Is there a way I can print out the request to see what it contains exactly?

I got it working. It was my ignorance. I had to redefine lookup_type in forms.py instead. Like this:
lookup_type = forms.ChoiceField(choices=LOOKUP_TYPE_CHOICES)
and not:
lookup_type = django_filters.ChoiceFilter(choices=LOOKUP_TYPE_CHOICES)
Because what django-filter was doing, it was trying to filter the lookup_type field, which does not exist in my models. It was throwing an error FieldError at/. Cannot resolve keyword 'lookup_type' into field, which I did not know about because another app I am using - django_tables2 modified this error to something else, which tricked me successfully.
It's probably a useless thread now but I just want to let pleople who tried to solve this, know.

Related

Django Error - MultiValueDictKeyError at /new_bid/5 'total_bid.' (Beginner help appreciated)

I'm creating a page on a site to allow users to 'bid' on items similar to ebay. When I try to enter a number (dollar amount) on the item on the site (to enter a bid) I get the error: MultiValueDictKeyError at /new_bid/5
'total_bid.'
The problem seems to be total_bid = request.POST["total_bid"] and I think the system believes it's None. I'm not sure why it thinks it's None because when entering the bid on the site, a number really is in the box, so if I type 100 meaning $100 bid, maybe the code is not actually taking in that number? So on POST it thinks there is nothing there?
I also tried total_bid = request.POST.get["total_bid"] with the .get part and also received an error.
I also tried adding something like "if total_bid is not none:" but I'm not sure how to do that with the syntax because I would need to declare total_bid = to something first.
I'm new to Django so additional information on how this works would be so helpful. I've already read a lot of posts on this site about this and similar errors but I'm having some trouble understanding.
views.py
def new_bid(request, listingid):
if request.method == 'POST':
auction_to_add = Listings.objects.get(id=listingid)
total_bid = request.POST["total_bid"]
bid = Bid.objects.create(user=request.user, listingid=auction_to_add, bid=total_bid)
auction_to_add.bids.add(bid)
auction_to_add.last_bid = bid
auction_to_add.save()
return render(request, "auctions/listing.html", {
"id": listingid,
})
else:
return render(request, "auctions/listing.html", {
"id": listingid,
})
The correct answer, which you've obviously looked at can be found here and it is as you said by using .get which does not raise an Exception.
What you are doing wrong at request.POST.get["total_bid"] is you are using [] instead of () which is invalid. You need to use request.POST.get("total_bid") because get is a method not a dictionary (or anything that can be accessed in a similar way).

in Django project. When annotate in views, getting error that item is not defined

I know, that this subject has been mentioned few times, but I can't find a solution for my problem. So please accept my apologies for a repeat request.
I have a condition-based filter, that doesn't work for me.
here is my models.py file:
class Itemslist(models.Model):
safety_stock = models.DecimalField(blank=True, null=True, max_digits=19, decimal_places=0)
current_stock = models.DecimalField(max_digits=19, decimal_places=0)
def above_below_ss(self):
ab = Decimal(self.current_stock-self.safety_stock)
return round(ab,0)
def __str__(self):
return self.item_n
Sorry, have to correct indentation, as it all belongs to one model class.
and here is what I have in views.py file:
from .models import *
def toorder(request):
# toorder=Itemslist.objects.all
sorted=Itemslist.objects.annotate(dontshow=above_below_ss()).exclude(dontshow__gt=0)
context={ 'sorted': sorted }
return render(request, 'toorder.html', context)
So here is a problem:
when I'm using
toorder=Itemslist.objects.all
everything works, but when I'm trying this:
sorted=Itemslist.objects.annotate(dontshow=above_below_ss()).exclude(dontshow__gt=0)
it doesn't.
Interesting thing is that it used to work, but my code crashed without a copy, (during a back-up, which is funny enough),
And now it doesn't work.
I'm getting this message:
NameError at /toorder
name 'above_below_ss' is not defined
Request Method: GET
Request URL: http://localhost:8000/toorder
Django Version: 2.2.5
Exception Type: NameError
Exception Value:
name 'above_below_ss' is not defined
Exception Location: /Users/artursjermolickis/projects/osmiocenter/mysite/itemlist/views.py in toorder, line 220
Python Executable: /Users/artursjermolickis/projects/osmiocenter/venv/bin/python3
Python Version: 3.7.4
Python Path:
['/Users/artursjermolickis/projects/osmiocenter/mysite',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python37.zip',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/lib-dynload',
'/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf']
If you need more pieces of code from me, please, just tell me what you need.
Really hope that you can help me here.
Here are additional comments to my question.
It is needed to filter the outcome by the mathematical function.
as an example I have posted safety_stock, and the solution, that is provided does work for that.
But as you have already mentioned, I need sort database, by a bit more complex function, so it's better to do it in models.py instead of doing it in vews.py that I can use it later. so the code, that I want to replace safety_stock with is:
def safe_stock(self):
if self.safety_stock ==0:
ss= (self.sales6mavgs()+self.stdev())*(self.lead_time+self.bookingterms)
else:
ss=Decimal(self.safety_stock)
return Decimal(ss.quantize(Decimal('1'),rounding=ROUND_UP))
So from your suggestions, I did understand, that I have to implement ExpressionWrapper.
How to implement it with ExpressionWrapper
Question is now answered, please see details below.
I have Added a Manager to my models.py:
class ToOrderManager(models.Manager):
def get_queryset(self):
return super(ToOrderManager, self).get_queryset().annotate(
dontshow=Round(ExpressionWrapper((F('current_stock')-F('safety_stock')), output_field=DecimalField()),0)
).annotate( leadtime=ExpressionWrapper(F('lead_time'), output_field=DecimalField())
).exclude(dontshow__gte=0).exclude(leadtime=0)
This lines have been added to my main model:
objects = models.Manager()
toorderobjects = ToOrderManager()
and my views.py looks like this now:
def toorder(request):
sorted=Itemslist.toorderobjects.all()
context={ 'sorted': sorted }
return render(request, 'toorder.html', context)
However in my case, it looks like I will have to perform Raw queries in my case, due to complicated calculations.
Thank you very much for knowledge sharing!!!
I dont think this dontshow=above_below_ss() was workign because it's an instance method that means that you first fetched a single record and then called it record.above_below_ss().
You can instead write this method as a part of the annotation using func and expression wrapper:
models.py
from django.db.models import Func
class Round(Func):
function = 'ROUND'
arity = 2
views.py
from django.db.models import DecimalField, ExpressionWrapper, F
from .models import Round
sorted=Itemslist.objects.annotate(dontshow=Round(ExpressionWrapper(F('current_stock') - F('safety_stock'), output_field=DecimalField()))).exclude(dontshow__gt=0)
If you want to reuse this you can move the query to manager and name it. Then, instead of each time writing long query, you'll simply use Itemslist.objects.whatever_name_you_chose()

module 'app.forms' has no attribute 'JobsFormSet'

I've have something like this in django: "module 'app.forms' has no attribute 'JobsFormSet'"
views.py:
http://pastebin.com/Kwup5s1x
forms.py:
http://pastebin.com/WyMuW3vn
I don't know where is a problem. I'm beginner in django. I'm pretty sure this code is correct, because I'm using from this tutorial (in polish)
Th error you get is
module 'app.forms' has no attribute 'JobsFormSet'
which probably comes from the lines
form = self.get_form()
jobs = forms.JobsFormSet(self.request.POST)
since you try to get JobsFormSet attribute in "forms" instead of "form".
Try this:
jobs = form.JobsFormSet(self.request.POST)

django - allow user to set something in database

I want to let user change language of a site by click on a country flag.
In my models.py file i have:
class RegularUser(models.Model):
(...)
language = models.CharField(max_length = 10, null=True, blank=True, choices=[(a, _(b)) for (a,b) in settings.LANGUAGES], verbose_name=_("Language"))
I also made there a function:
def set_language(self, new_lang):
lllang = self.language
lllang = new_lang
In my html file i have:
function setLang(lang){
language = document.getElementById("language")
lang_form = document.getElementById("language_form")
language.value= lang
lang_form.submit()
{{request.user.get_profile.set_language(lang) }}
}
This function in setted to some button as "onclick".
This should do two thing:
1. Change immediately the language (it's done)
2. Change uset language in the database, so next time when we will log in - it will be as we set it now (it doesn't work :( )
I'm getting an error such:
TemplateSyntaxError at /
Could not parse the remainder: '("lang")' from 'request.user.get_profile.set_language("lang")'
Just to tell - if I'll put :
{{request.user.get_profile.get_language}}
Then I'm getting code of my language, so it's fine.
get_language function from models.py:
def get_language(self):
if self.language:
return self.language
elif self.location and self.location.country:
return self.location.country.iso.lower()[:2]
else:
return None
Umm ... any help?
Am I just giving the "lang" in a wrong way, or I don't get something in Django?
In a Django template, you cannot call a Python function with parameters. See https://docs.djangoproject.com/en/1.4/topics/templates/#variables . That's why you get no error message when you write {{request.user.get_profile.get_language}} (actually, your function is called without parameters, and the resulting exception is swallowed by Django).
Also, you cannot use the lang parameter, which is a client-side JavaScript function parameter, in a Python function on the server side. Try calling the function using AJAX - you'll need to add another view function for this, and I strongly suggest you don't use bare JavaScript, but a library like jQuery.
For your actual problem (letting the user set his preferred language), there's already a function for that in Django's internationalization package.

django-piston: properly formatting POST data from a client application

I have a Django app running django-piston for the first time.
I've got a handler configured for a model and it's rigged for GET and POST.
GET works fine. Tried and true.
POST however is sucking. When I post data to it, I am getting this error
Responded: Piston/0.2.3rc1 (Django 1.2.4) crash report:
Method signature does not match.
Resource does not expect any parameters.
Exception was: cannot concatenate 'str' and 'dict' objects
I'm really not a pro at Python but some basic Googling reveals that this seems to be a rather generic Python TypeError
So here's some code.
urls.py (relevant parts)
auth = DjangoAuthentication()
ad = { 'authentication': auth }
word_handler = Resource(handler = WordHandler, **ad)
urlpatterns = patterns(
url(r'^word/(?P<word_id>[^/]+)/', word_handler),
url(r'^words/', word_handler),
)
handlers.py (relevant parts)
class WordHandler(BaseHandler):
allowed_methods = ('GET','POST',)
model = Word
fields = ('string', 'id', 'sort_order', ('owner', ('id',)),)
def read(self, request, word_id = None):
"""
Read code goes here
"""
def create(self, request):
if request.content_type:
data = request.data
print("Words Data: " + data)
existing_words = Word.objects.filter(owner = request.user)
for word in data['words']:
word_already_exists = False
for existing_word in existing_words:
if word["string"] == existing_word.string:
word_already_exists = True
break
if not word_already_exists:
Word(string = word["string"], owner = request.user).save()
return rc.CREATED
Basically it's not even getting to create() at all, or at least it seems not to. It just craps out with the aforementioned error, so I can't even see how it's receiving the data.
And just for the hell of it, here's the data I am trying to POST
{"words":[{"owner":{"id":1,"tags":null,"password":null,"words":null,"email":null,"firstname":null,"lastname":null,"username":null},"id":1,"sort_order":0,"tags":null,"string":"Another Test"},{"owner":{"id":1,"tags":null,"password":null,"words":null,"email":null,"firstname":null,"lastname":null,"username":null},"id":2,"sort_order":0,"tags":null,"string":"Here's a test"},{"owner":null,"id":0,"sort_order":0,"tags":null,"string":"Tampa"}]}
Any information at all would be extremely helpful.
I solved this for myself.
The relevant cause of the error is this line in the create method
if request.content_type:
which does not evaluate as True as I think the creators of the django-piston documentation intended. Even if the value is a string with a value.
Removing this line solved it. And I'm sure you can probably just do a string evaluation.
Not really sure what they were thinking there.

Categories

Resources