How to access stored user data in django? - django

I'm new to django, especially the storing of user data. Basically, I want to save user data searches. They put in a query into a search_bar and I want to save that query. I'm trying to create a list for each user with their search queries at user['search'] and the results of these queries at user['results']. However, I added some code and it does not seem to save the results.
Here is my code for user['results']. It's the same as for user['search']. I'm trying to save the query results by using request.session['result'] = query_result. The reason the results are not obvious is that they make a few choices between entering the query and seeing results.
from django.contrib.sessions.models import Session
request.session.modified = True
object_save = list(_objs.values('service__code'))
if not 'result' in request.session or not request.session['result']:
renderequest.session['result'] = [object_save]
request.session.save()
else:
result_list = request.session['result']
result_list.append(object_save)
request.session['result'] = result_list
request.session.save()
I'd expect this to be able to save and I can look at the searches in python manage.py shell.
When I try to pull all the session data with s = Session.object.get(pk='pk') and s['result'] I get nothing. s has no attribute 'result' is the error.
Maybe I'm completely not understanding user sessions, please help.

Related

How to delete data after fetch in a same action in Django?

I have a table in DB named Plan.
see code in models.py:
class Plan(models.Model):
id = models.AutoField(primary_key=True)
Comments = models.CharField(max_length=255)
def __str__(self):
return self.Comments
I want to fetch data(comments) from DB and after that data will be deleted. That means one data will be fetched once. And this data will be shown in the Django template.
I tried, see views.py
def Data(request):
data = Plan.objects.filter(id=6)
# latest_id = Model.objects.all().values_list('id', flat=True).order_by('-id').first()
# Plan.objects.all()[:1].delete()
context = {'data':data}
dataD = Plan.objects.filter(id=6)
dataD.delete()
return render(request,'data.html',context)
this code is deleting data from DB but not showing in the template.
How can i do this?
Your template must be updated because it fetch the data from the db one time only so if db is updated your template wouldn't change
From django docs:
Pickling QuerySets¶
If you pickle a QuerySet, this will force all the results to be loaded into memory prior to pickling. Pickling is usually used as a precursor to caching and when the cached queryset is reloaded, you want the results to already be present and ready for use (reading from the database can take some time, defeating the purpose of caching). This means that when you unpickle a QuerySet, it contains the results at the moment it was pickled, rather than the results that are currently in the database.
If you only want to pickle the necessary information to recreate the QuerySet from the database at a later time, pickle the query attribute of the QuerySet. You can then recreate the original QuerySet (without any results loaded) using some code like this:
>>> import pickle
>>> query = pickle.loads(s) # Assuming 's' is the pickled string.
>>> qs = MyModel.objects.all()
>>> qs.query = query # Restore the original 'query'.

Filtering out duplicate and none values from Django queryset

In a Django app, I can access user sessions and then get users_ids with flat=True. E.g. I'm doing:
Session.objects.filter(last_activity_gte=time_window).values_list('user_id',flat=True)
But the result is tainted by duplicates and None values. How do I perform the same query and filter out None or duplicates?
One way to do this is:
time_window = timezone.now() - timedelta(minutes=5)
user_ids = Session.objects.filter(last_activity_gte=time_window).values_list('user_id',flat=True)
user_ids = [id for id in user_ids if id is not None]
user_ids = set(user_ids)
But I wonder if I could have achieved that directly while querying the DB, which would be faster. Performance is crucial.
If anyone's interested, I'm using https://github.com/Bouke/django-user-sessions to be able to access Django session objects as ORM objects
To exclude empty user fields, filter by isnull.
(Session.objects
.filter(user__isnull=False)
.filter(last_activity_gte=time_window)
.values_list('user_id', flat=True))
To remove duplicates, you can use .distinct('user'), but that works only on some database back ends. MySQL doesn't seem to support it.

Django queryset - get created object from database and equal the values

I wrote a simple selenium test that fills all fields from submit form (adding news on site). There is one of them below (title field):
# type title
for t in range(2):
try:
title = driver.find_element_by_xpath("//*[#id='id_title']")
print "I found text!"
title.send_keys("SomeText")
except NoSuchElementException as e:
print "I didn't find it!"
else:
print "Retry"
It success and in /admin/news/ (Django) I am able to see my automatically filled new article.
Right now I'd like to check if the data send from this form equals to the data the is being stored on database.
Does anyone would explain how to use a proper queryset to retrieve these data and print the results ? I've created a new class and by a logic I think it's gonna be something like below:
class NewsModelTestCompare(TestCase):
def test_creating_news(self):
# getting object
n = News.objects.get(title="SomeText")
self.assertEqual(News.objects.get(pk=n.id), n)
To check if the data is already in database, you could first query on News model with the data submitted from the form and check if database returns any result, like:
matching_objects = News.objects.filter(title="SomeText")
# this means the query returned at least one result
self.assertNotEqual(matching_objects.count(), 0)

Add field to Django queryset

I'm working on a small project, with an existing database, filled with data. Every day we run a task to get a number of records and email the results. For one of the values we email, we need to perform a calculation (string replacement) on an existing field. We now do this using a model method. But to do this, we need to iterate over all the objects in the queryset.
How can I add/extend a calculated field to the queryset at the moment that we run the query? Note that this is not an existing field in the model, and that we have to perform some replacements on an existing field. Can I use a custom model manager for this? And if so, do you have an example?
The model method:
def get_application_dir(self):
trails = {
'xxx': '/abc/123',
'yyy': '/xyz/789',
}
app = self.application
file = self.filename
if app in trails:
traillen = len(trails[app])
if file[-traillen:] == trails[app]:
return file[:-traillen]
return file
The use in the view:
if files:
result['i'] = []
for f in files:
a = {
'application_name': f.application_name,
'directory': f.get_application_dir()
}
result['i'].append(a)
So, I don't want to perform the loop above, by just getting the value/field from the ORM. Is this possible? Maybe by creating a custom model manager, and extending the queryset?
Thanks in advance.

Django - storing queryset in request.session still queries the db - why?

def mysearch(request):
"""This view builds a Q object query based on which fields are filled."""
if 'submit' in request.POST:
# build Q object depending on fields submitted
q = Q()
if request.POST['first_field']:
q &= Q(firstfield__icontains = request.POST['first_field'])
...
if request.POST['sixth_field']:
q &= Q(sixthfield__icontains = request.POST['sixth_field'])
results_list = MyModel.objects.filter(q)
count = len(results_list)
# store results
request.session['results_list'] = results_list
request.session['count'] = count
# 'p' is an arbitrary marker to detonate pagination of a page other than 1
if 'p' in request.GET:
results_list = request.session['results_list']
count = request.session['count']
if count and count > 0:
...
# pagination code
...
else:
pass
return render_to_response('search_results.html',
locals(), context_instance=RequestContext(request))
All works well in my templates using the paginator. The problem is that Django debug toolbar tells me that I am hitting the database the same number of times on pages > 1 than I am on the first page. Why is this? In fact - why is it hitting the database at all? Shouldn't the whole results_list be being pulled from request.session? Any advice much appreciated.
You're saving a queryset object in the session. Querysets are like SQL statements, but they cache the results. You haven't run the query when you put it in the session, so what you're storing is essentially just the query. When it gets pulled out it's still just a query that hasn't run, so the queryset gets run again. To ensure that you're storing just the actual results, do this:
request.session['results_list'] = list(results_list)
and to save you another query when you find count you can...
request.session['count'] = len(request.session['results_list'])
Also keep in mind that session data is (by default) saved in the database, so you might not be doing yourself any favors by storing a python pickled representation of the full data. It might in fact be faster just to go to the original table and pull it out that way.