I am a beginner in Django as well as Python.
I first generate 50 random numbers and store them in a list and then in a text field in model User.
def generate(request, user_id):
easy = [] * 55
cnt = 0
while cnt < 50:
random_id = random.randint(1, 200)
if random_id not in easy:
easy.append(random_id)
cnt += 1
current_user = User.objects.get(pk=user_id)
current_user.question_array = json.dumps(easy)
return render(request, 'comp/question.html', {'easy': easy[0], 'question_id': 1,'user_id':user_id})
But when I try to retrieve the value from field I get only 0.
When I try to use it as a list it shows an error of "int object cannot be subscript".
This is the code to retrieve it:
def next(request,user_id, question_id):
current_user = User.objects.get(pk=user_id)
jsonDec = json.decoder.JSONDecoder()
easy = jsonDec.decode(current_user.question_array)
return render(request, 'comp/question.html',
{'easy': easy, 'question_id': int(question_id) + 1,'user_id':user_id})
I have used the answer to this question given by mindthief to store a list in a table.
Edit:
My main problem is that the list is not getting stored in database. Any ideas why?
You need to add a .save() call to save the data to the db:
current_user = User.objects.get(pk=user_id)
current_user.question_array = json.dumps(easy)
current_user.save()
...
BTW, you can also use random.sample():
easy = random.sample(range(200), 50) # in python 2.x use xrange()
and json.loads():
easy = json.loads(current_user.question_array)
If you use PostgreSQL (highly recommended) you can even use a JsonField.
And finally, if the questions are stored in another model (Question), consider using a ManyToManyField instead.
Related
I'm using django-auth-ldap and I'm trying to get all users from LDAP server, I didn't find a way to do so, the authenticating is working in the backend, here is my code
#api_view(['GET'])
def users(request):
l = ldap.initialize(backend.AUTH_LDAP_SERVER_URI)
l.simple_bind_s(backend.AUTH_LDAP_BIND_DN, backend.AUTH_LDAP_BIND_PASSWORD)
users = LDAPBackend().populate_user('*') #this line is returning None
l.unbind_s()
print (users)
serializer = userSerializer(users, many=True)
return Response(serializer.data)
I know that line is incorrect LDAPBackend().populate_user('*')
but I really need to get all users with something like this : conn.search('ou=users, dc=example,dc=com', '(objectclass=person)', attributes=['uid', 'cn', 'givenName', 'sn', 'gidNumber'])
(this is how I did with another library called ldap3)
Thank you
You can do something like this below
def get_users():
conn = ldap.initialize(LDAP_URL)
results = conn.search_s(GROUP_DN, ldap.SCOPE_ONELEVEL, '(cn=*)')
# get all non-empty uniqueMember of all groups (list of list), flattern the list and get only unique value
users_dn = set(list(chain.from_iterable(filter(lambda x: x, [x[1].get('uniqueMember') for x in results]))))
users = [x.split(',')[0].split('=')[1] for x in users_dn]
return users
I have a text area in which user inputs multiple values in different line and i want to get object for every single line in text area and send it to template. How i should do it.?
if request.method == 'GET':
search = request.GET.get('search')
slist = []
for i in range(4):
slist.append(search.splitlines()[i])
sdata = Stock.objects.all().filter(slug=slist)
return render(request, 'stocks/searchbar.html', {'sdata':sdata})
I'm trying to do it in this way.
You need to do something like this:
sdata = Stock.objects.filter(slug__in=search.splitlines())
Since search.splitlines() returns a list and slug is, I assume, a CharField, you need the in clause in your query.
My Django project need to acquire one list after processing in one function of views.py.
def acquire(request):
import sys
n = []
for topic in Topic.objects.filter(owner=request.user).order_by("date_added"):
entries = topic.entries.all()
q = entries.text
n.append(q)
return render(request, "projects/topics.html", n)
The list "n" above need to be transferred to another function of views.py for the information in another "results.html" page.
def results(request):
data = XXXX
return render(request, "projects/results.html", {"datas": data})
How could I edit "XXX" in results function to transfer the "n" list?
You can write a utility function that can be used by both views and stores the data for the current session:
def acquire(request):
data = _get_data(request)
return render(request, "projects/topics.html", {'data': data})
def results(request):
data = _get_data(request)
return render(request, "projects/results.html", {'data': data})
# this is not a view, but a utility function
def _get_data(request)
# this will try to use the data generated in a previous request of
# the same session. So the data might be stale by now
if not 'user_entries' in request.session:
n = []
for topic in Topic.objects\
.filter(owner=request.user)\
.order_by('date_added')\
.prefetch_related('entries'): # prefetch avoids the nested queries
for entry in topic.entries.all():
n.append(entry.text)
request.session['user_entries'] = n
return request.session['user_entries']
You can declare the list n outside of the function so you can use it wherever you want, like:
n = []
def acquire(request):
import sys
for topic in Topic.objects.filter(owner=request.user).order_by("date_added"):
entries = topic.entries.all()
q = entries.text
n.append(q)
return render(request, "projects/topics.html", n)
def results(request):
data = n
return render(request, "projects/results.html", {"datas": data})
You have to remember that whatever variable you set, it only lives within the view/function as Django is stateless. That's why you have a database and cookies.
This is how you do it. Unless that list has thousands and thousands of entries, this will be fast.
def results(request):
data = []
for topic in Topic.objects.filter(owner=request.user).order_by("date_added"):
entries = topic.entries.all()
q = entries.text
data.append(q)
return render(request, "projects/results.html", {"datas": data})
If you want to be really fast, you could change the request and work on the database level and create a join. Something along the lines of this (I'm a bit rusty)
data = Entries.objects.filter(topic__owner=request.user).order_by("topic__date_added").values("text")
I have one django project. It has one function in view.py to process the data from the inputs to give the output for other function. However the processing time for the function is kind of long. I want to fulfill the instant demonstration of the processed output. How could I achieved that? The following processing() function is for the processing purpose. And the output 'user_entries' is for the demonstration in results() as followed.
def processing(request):
import sys
n = []
for topic in Topic.objects.filter(owner=request.user).order_by("date_added"):
entries = topic.entries.all()
m = []
for p in entries:
q = p.text
m.append(q)
n.append(m)
list = []
start(list, n)
request.session['user_entries'] = list
return request.session['user_entries']
def results(request):
data = processing(request)
return render(request, "project/results.html", {"datas": data})
In the start() function of the processing() function. There is one part list.append() to add new output into list. But it seems that the new appended list cannot be transferred and show the instant results in project/results.html?
What you're doing could likely be done a lot more simply.
def results(request):
return render(
request,
"project/results.html",
{
"user_entries": Entry.objects.filter(topic__owner=request.user),
"start_values": "...", # Whatever start is appending...
},
)
Since you have a foreign key from entry to User, you could also use request.user.topic_set.all() to get the current user's topics.
Or, if you actually do need those lists nested...
# ...
"user_entries": (
topic.entries.all() for topic in
Topic.objects.filter(owner=request.user)
),
# ...
Just based on what you're showing us, it seems like your ordering -- for both Topic and Entry -- should probably have a sensible default set in, e.g., Topic.Meta.ordering, which in this case would probably look like this:
class Topic(models.Model):
# ...
class Meta:
ordering = ("date_added",)
# ...
That way, in this and most other cases, you would not have to apply .ordering(...) manually.
I'm trying to build a search system, and I want to search by multiple fieldsname, state, city, in my django models. I wrote the below code, yet I've been unable to figure out how to go about it. I use Q but it seems not working:
views.py:
def data_consulting(request):
if request.method == 'POST':
form = FilterForm(request.POST)
if form.is_valid():
conditions = [('toBuy', form.cleaned_data['toBuy']), ('name__contains', form.cleaned_data['searchName']),(('price__gte', form.cleaned_data['searchPriceBegin']), ('price__lte',form.cleaned_data['searchPriceEnd'])),(('calories__gte', form.cleaned_data['searchCalorieBegin']), ('calories__lte', form.cleaned_data['searchCalorieEnd'])), (('date__gte',form.cleaned_data['DateBegin']), ('date__lte', form.cleaned_data['DateEnd']))]
all_products = Product.objects.filter(reduce(operator.or_, [Q(condition) for condition in conditions]))
send = True
all_products = Product.objects.filter(reduce(operator.or_, [Q(condition) for condition in conditions]))
else:
form = FilterForm()
all_products = Product.objects.all()
return render(request, 'mealManager/data_consulting.html', locals())
Have a think about what
reduce(operator.or_, [Q(condition) for condition in conditions])
becomes with e.g. [('toBuy', 'bread'), ('name__contains', 'bread')]. It becomes
Q(('toBuy', 'bread')) | Q(('name_contains', 'bread'))
which is obviously wrong syntax, since Q rather needs kwargs than a tuple:
Q(toBuy='bread') | Q(name__contains='bread')
that's where the ** operator comes to the rescue. If you get data like this:
[{'toBuy': 'bread'}, {'name__contains': 'bread'}]
which may be accomplished by simply changing the conditions assignment you can then do
reduce(operator.or_, [Q(**condition) for condition in conditions])
which translates in the particular case to
Q(toBuy='bread') | Q(name__contains='bread')
which is exactly what we need.