Django Haystack has a blank `text` value - django

Reference:
>>> from haystack.query import SearchQuerySet
>>> sqs = SearchQuerySet().all()
>>> sqs[0].text # ... or whatever your document=True field is.
If you get back either u'' or None, it means that your data isn’t making it into the main field that gets searched. You need to check that the field either has a template that uses the model data, a model_attr that pulls data directly from the model or a prepare/prepare_FOO method that populates the data at index time.
I couldn't understand why my .text return nothing. Could someone explain the above notes? More specifically, I don't understand those I highlighted in bold.

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'.

Django - How to check all the attributes of a queryset?

I am looking a way to get all the attributes of a variable after we set the value in it using queryset.
For example...refer below code... using user.id or user.first_name i can get the value for that attribute. But if i want to check what all other attributes it has? Is there a way i can get.
If we use user then it will just return which is what we have defined in admin.py.
Code, i am using Django Shell
from django.contrib.auth.models import User
user=User.objects.get(id=1)
user.first_name # Will return some value say testUser
user.id # will return some value say 1
I guessing what you are saying is you want to print all attributes of an object instead of QuerySet
To print all attributes of an object you can do the follow:
from django.contrib.auth.models import User
user=User.objects.get(id=1)
print(user.__dict__)
But if you just what to find out what django default user models fields are, you can check this docs:
https://docs.djangoproject.com/en/3.0/ref/contrib/auth/
Django returns a tuple of fields associated with a model if you want.
Django 3.0:
from django.contrib.auth.models import User
User._meta.get_fields()
Adding to #MarkL 's answer:
You can pretty print it for better readability.
from django.contrib.auth.models import User
from pprint import pprint # new
user=User.objects.get(id=1)
pprint(user.__dict__) # new ----> pprint() instead of print()
Another way which I always prefer using over __dict__ is vars() method:
user=User.objects.get(id=1)
pprint(vars(user))
Both return the same result but to me vars() is more convenient to write than the dunder dict method i-e __dict__, coz I am too lazy to write 4 underscores.
Building on MarkL's answer, here is the same thing, but with nicer formatting:
[f"{key}: {value}" for key, value in user.__dict__.items()]
(Sorry, I don't have enough rep to post this as a comment.)

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)

Using django fields validation for external values

I have model with one field(this is synthetic example):
model Tank:
oxygen = models.PositiveSmallIntegerField(
_("Oxygen %"),
help_text="%",
default=21,
validators=[MinValueValidator(21.0), MaxValueValidator(50.0)],
null=True,
)
And I parse some files with data. I want to validate input data before write it model instance. Something like this
oxygen = get_raw_data()
Tank.oxygen.validate(oxygen) # this is wrong I know :)
# if value is valid do something
# else do something
What should I write instead of Tank.oxygen.validate(oxygen)?
I can duplicate validation logic or validate data when save model instance, but maybe somebody know better solution.
You need to actually create an instance with the data, then call full_clean() on it:
my_tank = Tank(oxygen=oxygen)
my_tank.full_clean()
If you only want to validate one field, then I suggest you use a form.Field class to do it:
from django import forms
from django.core.exceptions import ValidationError
oxygen_field = forms.IntegerField(required=True, min_value=21, max_value=50)
def is_oxygen_valid(value):
try:
oxygen_field.clean(value)
except ValidationError:
return False
else:
return True
Testing:
>>> is_oxygen_valid(None)
False
>>> is_oxygen_valid(11)
False
>>> is_oxygen_valid(55)
False
>>> is_oxygen_valid('hello')
False
>>> is_oxygen_valid(list())
False
>>> is_oxygen_valid(45)
True
I'm assuming that you are going to be validating the oxygen field first, and then deciding what to do depending on the result. You could adapt this to any other field you need. Just find the appropriate FormField class, and any Validators you might need, and use that instead.

Django Database querying differences

I am going through the creation of the Polls app again, in the Django Docs. I wanted to ask again about one particular thing they do in the django database. The code is shown below:
>>> from polls.models import Poll, Choice
# Make sure our __unicode__() addition worked.
>>> Poll.objects.all()
[<Poll: What's up?>]
# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Poll.objects.filter(id=1)
[<Poll: What's up?>]
>>> Poll.objects.filter(question__startswith='What')
[<Poll: What's up?>]
# Get the poll that was published this year.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Poll.objects.get(pub_date__year=current_year)
<Poll: What's up?>
# Request an ID that doesn't exist, this will raise an exception.
>>> Poll.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Poll matching query does not exist. Lookup parameters were {'id': 2}
# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Poll.objects.get(id=1).
>>> Poll.objects.get(pk=1)
<Poll: What's up?>
# Make sure our custom method worked.
>>> p = Poll.objects.get(pk=1)
>>> p.was_published_recently()
True
# Give the Poll a couple of Choices. The create call constructs a new
# Choice object, does the INSERT statement, adds the choice to the set
# of available choices and returns the new Choice object. Django creates
# a set to hold the "other side" of a ForeignKey relation
# (e.g. a poll's choices) which can be accessed via the API.
>>> p = Poll.objects.get(pk=1)
# Display any choices from the related object set -- none so far.
>>> p.choice_set.all()
[]
# Create three choices.
>>> p.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> p.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = p.choice_set.create(choice_text='Just hacking again', votes=0)
# Choice objects have API access to their related Poll objects.
>>> c.poll
<Poll: What's up?>
If you take a look at the variable c, you will see that it is created using this, p.choice_set.create(choice_text='Just hacking again', votes=0). Now if you created it instead with this: c = p.choice_set.filter(id=3), and when you type in c.poll, it will give you an error. Why does this happen? The console gives me this error : AttributeError: 'Poll' object has no attribute 'create', but I do not understand what it means.
Also, is there any way of getting c.poll to give you an output without having to create a new choice?
--
Thanks in advance
c = p.choice_set.filter(id=3) won't return a single choice object. It returns a queryset composed of a single choice object because, obviously, there is just one object with the same id. Querysets are iterables, which means that if you want to obtain the choice object from that variable it should be: c = p.choice_set.filter(id=3)[0]
That is the difference with choice_set.create: create returns the single created object.
Now, that's not the way to do it. When you know you are querying for a single object, use get.
c = p.choice_set.get(id=3).
See querying documentation for further details.