Django error 'RawQuerySet' object has no attribute 'all' - python

I got this error message if I'm using SQL statement to populate data in dropdown.
Error message
'RawQuerySet' object has no attribute 'all'
Model.py
#python_2_unicode_compatible # only if you need to support Python 2
class FacebookAccount(models.Model):
user = models.ForeignKey(User)
account_description = models.CharField(max_length=50)
facebook_application_id = models.CharField(max_length=50)
facebook_application_secret = models.CharField(max_length=50)
ouath_token = models.CharField(max_length=500)
status = models.BooleanField(default=False)
def __str__(self):
return self.account_description
#python_2_unicode_compatible # only if you need to support Python 2
class FacebookFanPage(models.Model):
facebook_account = models.ForeignKey(FacebookAccount)
fan_page_description = models.CharField(max_length=50)
fan_page_id = models.CharField(max_length=30)
fan_page_access_token = models.CharField(max_length=500, null=True)
def __str__(self):
return self.fan_page_description
class Campaign(models.Model):
aList = (
('1', 'Send replies to inbox messages'),
('2', 'Post replies to users comments')
)
user = models.ForeignKey(User)
campaign_name = models.CharField(max_length=50)
autoresponder_type = models.CharField(max_length=10, choices=aList, null=True)
facebook_account_to_use = models.ForeignKey(FacebookAccount)
set_auto_reply_for_fan_page = models.ForeignKey(FacebookFanPage)
message_list_to_use = models.ForeignKey(PredefinedMessage)
#reply_only_in_this_hourly_interval
reply_only_for_this_keyword = models.CharField(max_length=50, null=True)
View.py
def autoresponder_create(request, template_name='autoresponder/autoresponder_form.html'):
if not request.user.is_authenticated():
return redirect('home')
form = AutoresponderForm(request.POST or None)
form.fields["set_auto_reply_for_fan_page"].query = FacebookFanPage.objects.raw('SELECT * '
'FROM fbautoreply_facebookfanpage '
'JOIN fbautoreply_facebookaccount ON fbautoreply_facebookfanpage.facebook_account_id = fbautoreply_facebookaccount.id '
'WHERE fbautoreply_facebookaccount.user_id = %s ', [str(request.user.id)])
if form.is_valid():
form = form.save(commit=False)
form.user = request.user
form.save()
return redirect('autoresponder_list')
return render(request, template_name, {'form':form})

As the first comment says it seems like you are calling all() on queryset. You dont have to call .all() after executing raw sql queries, if you are assigning that to a variable since that variable already includes all objects fetched by your query.
In [6]: t = Team.objects.raw('SELECT * FROM core_team')
In [7]: t
Out[7]: <RawQuerySet: SELECT * FROM core_team>
In [8]: t[0]
Out[8]: <Team: test>
In [9]: [x for x in t ]
Out[9]: [<Team: test>, <Team: team2>, <Team: adminTeam>, <Team: team4>]
and if you call t.all()
In [11]: t.all()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-11-2ce0015f044f> in <module>()
----> 1 t.all()
AttributeError: 'RawQuerySet' object has no attribute 'all'
In [12]:
So it seems like you are calling all() on after executing a sql raw query. Remove that piece of code and it will be solved.
You can refer to this section of django docs if you want to use better ways to execute a sql query.
Edit
Try changing form.fields["set_auto_reply_for_fan_page"].query to form.fields["set_auto_reply_for_fan_page"].queryset

you can create view in sql or select query
then
you can manupulete this query with raw sql
for example you want to make filter with like contidion.
firs select all joining table with view or select
the query is first query slect all
new query is manuplulated query with raw.
not: select syntax for postgressql
if request_post:
if request_post.get('name'):
name = request_post.get('name')
name = '%'+name+'%'
condition = "WHERE account_name like"
s = '%s'
new_query = f"""{query} {condition} {s} """
queryset=TestOrderDetail.objects.raw(new_query,[name] )

form.fields["set_auto_reply_for_fan_page"].choices = [(None, '---'),] + [ (x.id, x.name ,) for x in FacebookFanPage.objects.raw('''select id, name from dual''')]

Related

Unable to assign a Foreign Key in DJango

I am trying to save data into a mysql database using 2 tables main and public, but am unable to store data into the public table.
ERROR: ValueError: Cannot assign "4": "public.unq_id" must be a "main" instance.
Models.py:
class main(models.Model):
unq_id = models.BigAutoField(primary_key=True)
email = models.CharField(max_length=80)
password = models.CharField(max_length=256)
first_name = models.CharField(max_length=80)
last_name = models.CharField(max_length=80)
dob = models.CharField(max_length=80)
phone = models.BigIntegerField(default=0)
status = models.CharField(max_length = 12, default = 'active')
def __str__(self):
return self.unq_id
def verify_password(self, raw_password):
return pbkdf2_sha256.verify(raw_password, self.password)
class public(models.Model):
unq_id = models.OneToOneField(main, on_delete=models.CASCADE, primary_key = True)
lang = models.CharField(max_length=80)
expert = models.CharField(max_length=80)
country = models.CharField(max_length=80, default = "None")
Views.py:
Email1=request.POST['Email']
a = main.objects.filter(email = Email1).exists()
if a is True:
error = "Email taken"
return render(request, 'Main/registration.html',{'error':error})
password1=request.POST['password']
password = pbkdf2_sha256.encrypt(password1,rounds=12000,salt_size=32)
Fname=request.POST['Fname']
Lname=request.POST['Lname']
DOB=request.POST['dob2']
lang= request.POST['lang']
phone=request.POST['phone']
c = main.objects.filter(phone = phone).exists()
if c is True:
error = "phone number taken"
return render(request, 'Main/registration.html',{'error3':error})
country=request.POST['country']
r = countrycode.objects.filter(country = country).exists()
if r is True:
s = countrycode.objects.get(country = country)
country = s.code
main2=main(email=Email1,password=password,first_name=Fname,last_name=Lname,dob=DOB,phone=phone)
main2.save()
mainobj= main.objects.get(email = Email1)
public2=public(lang=lang,expert="false",country=country,unq_id=mainobj.unq_id)
public2.save()
When I look in my database, the mainobj gets stored but the public object doesn't get saved; despite having the same "unq_id"
Please do help , thank you
The error is telling you that when you instantiate the public object you are trying to pass a "4" string / int, as an unq_id parameter when in fact you defined a OneToOne relation that is at the instance level relationship, so your public object in the unq_id attribute expects an object / instance of main.
Example:
main_test = main(email='test#test.com', password='test', ...)
public_test = public(unq_id=main_test,...)
In the Django documentation you can find all the aspects about this type of relationship, such as its restrictions or how the objects are retrieved when a query is made to the DB.

How to fix error 500 from query None?

I want to list related categories saved on a db field called "related"
my code
def category(request, slug):
related = Article.objects.filter(slug__icontains=slug).values('related').first()
return render(request,'category.html',{'related':related}
y try with:
option 1:
In case of a return, a None on related I assign only the category
Article.objects.filter(Q(slug__icontains=slug) | Q(category__icontains=slug))
option 2:
if related is None:
related = Article.objects.filter(category__icontains=slug).values('category').first()
else:
related = related.get('related').split(',')
error:
'NoneType' object has no attribute 'get'
In my DB I checked with the following query:
SELECT * FROM `article` WHERE slug like '%internet%'
And I get 0 records, so the error is coherent
But I don't see how to assign in that case
SELECT * FROM `article` WHERE category like '%internet%'
where I have 22 results
model:
class Article(models.Model):
category = models.CharField(max_length=2000, blank=True, null=True)
related = models.CharField(max_length=2000, blank=True, null=True)
text = models.CharField(max_length=2000, blank=True, null=True)
slug= models.SlugField(max_length=255, unique=True)
class Meta:
managed = False
db_table = 'article'
def __str__(self):
return u'%s %s %s %s' % (self.categoria,self.related, self.text, self.slug)
option 3:
Article.objects.filter(Q(slug__icontains=slug) | Q(category__icontains=slug)).values_list("related", flat=True).distinct()
error too many values to unpack (expected 2)
error line 37 with this:
relateds = related.get('related').split(',')
all the process:
def category(request, slug):
related = Article.objects.filter(Q(slug__icontains=slug) | Q(category__icontains=slug)).values('related').distinct()
temp=[]
for x in relateds:
temp.append(x.replace(" ","-").replace("é","e"))
relateds=temp
With option 2 you could try it this way
related = Article.objects.filter(slug__icontains=slug).values('category').first()
if not related:
related = Article.objects.filter(category__icontains=slug).values('category').first()
If I understand correctly what you wanted to do, you can use option 1 with values_list method.
Article.objects.filter(Q(slug__icontains=slug) | Q(category__icontains=slug)).values_list("related", flat=True).distinct()
This query will return all unique related fields for the slug you have searched. You can also check and remove empty values in filter by related__isnull=False
The views.py file should look like as below finally. I've corrected the typos and indentations.
def category(request, slug):
if slug is None:
related = Article.objects.filter().values_list('related', flat=True).distinct()
else:
related = Article.objects.filter(Q(slug__icontains=slug) | Q(category__icontains=slug)).values_list('related', flat=True).distinct()
relateds=[]
for x in related:
relateds.append(x.replace(" ","-").replace("é","e"))
return render(request,'category.html',{'related': relateds})

Is it possible to pass values from a query to models.py in django?

I'm trying to make an app in which a person inserts an id and a birthday date of someone and outputs something. My
doubt here is: having a query (from oracle) with the several id and birthday dates using:
connection = cx_Oracle.connect(...)
cursor = connection.cursor()
cursor.execute("query")
My question is: Is it possible to pass some values from the query to my models.py file? For example, in my "models.py" file I have a field called "id" and I would like to pass all the records from the query in the field "doente" to the "models.py" file as "id".
My form is something like this:
Form
and my models.py file is:
class PatientTutor(models.Model):
id = models.AutoField(primary_key=True)
username = models.CharField(max_length = 8)
patientID = models.CharField(max_length = 8)
created = models.DateTimeField(auto_now_add = True)
birthday = models.DateField(blank=True, default=None)
birthdayPatient = models.DateField(blank=True, default=None)
where the values from the fields: "GTS do autorizante" and "Data de nascimento do autorizante" are in my models.py and the values from the fields: "GTS do autorizado" and "Data de nascimento do autorizado" come from the query. I would like to copy all the values from the query to my models.py file but I don't know if that is possible.
EDIT:
my views.py file looks like this so for:
def mostraFormTutorPaciente (request):
return render(request, 'CartaoCliente/mostraFormTutorPaciente.html')
def TutorPaciente (request):
if request.method == 'POST':
AutorizanteGTS = PatientTutor.objects.get(id = request.POST['AutorizanteGts'])
NascAutorizante = PatientTutor.objects.get(birthday = request.POST['DtNascAutorizante'])
connection = cx_Oracle.connect("....")
cursor = connection.cursor()
cursor.execute("select t_doente, doente, nome, dt_nasc, telef1, telef2" + \
"from gh.sd_doente where doente<>'" + patientID + \
"'and nvl(flag_anulado, 'N')<>'S' and dt_nasc >= sysdate-18*365 and (trim(telef1) in (" + inClause + ") or trim(telef2) in (" + inClause + "))")
registos =[]
for record in cursor:
registos.append(record)
return render(request, 'CartaoCliente/TutorPaciente.html', )
Here I try to get the values that came from the post and are in my models.py and when I made the connection to the oracle db I try to get the other values that came from the post.
Yes, it is possible.
When the form is posted, you can get the data from the oracle database, and then save it to a model object.
Use this example view to see how it would work:
def my_view(request):
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
# get the data from the oracle DB
oracle_data = some_function()
# create a model object that saves the data
obj = MyObject.objects.create(
birthday=oracle_data['birthdate']
some_other_field=some_value
)
# everything worked out, return a response
return render(request, 'some-template.html')
# for data was not valid, return an error
return render(request, 'error-template.html')

How to print the query of .get queryset in django

How can I know the query when doing a .get queryset in django
I have this model:
class Artist(EsIndexable, models.Model):
name = models.CharField(max_length=50)
birth_date = models.DateField()
And I did this in the shell:
x = Artist.objects.get(name="Eminem")
print x.query
Then I got the error:
AttributeError: 'Artist' object has no attribute 'query'
.get returns an instance, not a queryset.
To see the query that is done, do the same thing but with .filter, which does return a queryset:
queryset = Artist.objects.filter(name="Eminem")
print queryset.query
x = queryset.get()
from django.db import connection
x = Artist.objects.get(name="Eminem")
print connection.queries[-1]

Django-powered library checkout system

I am working on a library system to manage certain items in our office, I don't need a full-blown integrated library system so I decided to hand roll one with Django.
Below is a simplified version of my model:
class ItemObjects(models.Model):
# Static Variables
IN_STATUS = 'Available'
OUT_STATUS = 'Checked out'
MISSING = 'Missing'
STATUS_CHOICES = (
(IN_STATUS, 'Available'),
(OUT_STATUS, 'Checked out'),
(MISSING, 'Missing'),
)
# Fields
slug = models.SlugField(unique=True)
date_added = models.DateField(auto_now_add=True)
last_checkin = models.DateTimeField(editable=False, null=True)
last_checkout = models.DateTimeField(editable=False, null=True)
last_activity = models.DateTimeField(editable=False, null=True)
status = models.CharField(choices=STATUS_CHOICES, default=IN_STATUS, max_length=25)
who_has = models.OneToOneField(User, blank=True, null=True)
times_out = models.PositiveIntegerField(default=0, editable=False)
notes = models.CharField(blank=True, max_length=500)
history = models.TextField(blank=True, editable=False)
pending_checkin = models.BooleanField(default=False)
pending_transfer = models.BooleanField(default=False)
At first I was using a method on ItemObject to process checking out an item to a user and who_has was an EmailField because I couldn't get a CharfField to populate with the logged in user's name, but I figured using a OneToOneField is probably closer to the "right" way to do this.. While who_has was an EmailField, the following method worked:
def check_out_itemobject(self, user):
user_profile = user.get_profile()
if self.status == 'Available' and self.who_has == '':
self.status = 'Checked out'
self.who_has = user.email
self.last_checkout = datetime.datetime.now()
self.last_activity = datetime.datetime.now()
self.times_out += 1
if self.history == '':
self.history += "%s" % user_profile.full_name
else:
self.history += ", %s" % user_profile.full_name
if user_profile.history == '':
user_profile.history += self.title
else:
user_profile.history += ", %s" % self.title
else:
return False # Not sure is this is "right"
user_profile.save()
super(ItemObjects, self).save()
Now that I am using a OneToOneField this doesn't work, so I started looking at using a subclass of ModelForm but none of the cases I saw here on SO seemed to apply for what I am trying to do; my form would be a button, and that's it. Here are some of the questions I looked at:
Django: saving multiple modelforms simultaneously (complex case)
(Django) (Foreign Key Issues) model.person_id May not be NULL
django update modelform
So was I on the right track with a sort of altered save() method, or would a ModelForm subclass be the way to go?
EDIT/UPDATE: Many thanks to #ChrisPratt!
So I am trying to get Chris Pratt's suggestion for showing ItemHistory to work, but when I try to render it on a page I get an AttributeError that states "'User' object has no attribute 'timestamp'". So my question is, why is it complaining about a User object when last_activity is an attribute on the ItemObject object ?
My view:
#login_required
def item_detail(request, slug):
item = get_object_or_404(Item, slug=slug)
i_history = item.last_activity
user = request.user
return render_to_response('items/item_detail.html',
{ 'item' : item,
'i_history': i_history,
'user' : user })
I do not see why a User object is coming up at this point.
EDIT2: Nevermind, history is clearly a M2M field whose target is User. That's why!
Assuming users will log in and check out books to themselves, then what you most likely want is a ForeignKey to User. A book will only have one User at any given time, but presumably Users could check out other items as well. If there is some limit, even if the limit is actually one per user, it would be better to validate this in the model's clean method. Something like:
def clean(self):
if self.who_has and self.who_has.itemobject_set.count() >= LIMIT:
raise ValidationError('You have already checked out your maximum amount of items.')
Now, you checkout method has a number of issues. First, status should be a defined set of choices, not just random strings.
class ItemObject(models.Model):
AVAILABLE = 1
CHECKED_OUT = 2
STATUS_CHOICES = (
(AVAILABLE, 'Available'),
(CHECKED_OUT, 'Checked Out'),
)
...
status = models.PositiveIntegerField(choices=STATUS_CHOICES, default=AVAILABLE)
Then, you can run your checks like:
if self.status == self.STATUS_AVAILABLE:
self.status = self.STATUS_CHECKED_OUT
You could use strings and a CharField instead if you like, as well. The key is to decouple the static text from your code, which allows much greater flexibility in your app going forward.
Next, history needs to be a ManyToManyField. Right now, your "history" is only who last checked the item out or what the last item the user checked out was, and as a result is pretty useless.
class ItemObject(models.Model):
...
history = models.ManyToManyField(User, through='ItemHistory', related_name='item_history', blank=True)
class ItemHistory(models.Model):
CHECKED_OUT = 1
RETURNED = 2
ACTIVITY_CHOICES = (
(CHECKED_OUT, 'Checked Out'),
(RETURNED, 'Returned'),
)
item = models.ForeignKey(ItemObject)
user = models.ForeignKey(User)
activity = models.PostiveIntegerField(choices=ACTIVITY_CHOICES)
timestamp = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-timestamp'] # latest first
Which then allows you to get full histories:
some_item.history.all()
some_user.item_history.all()
To add a new history, you would do:
ItemHistory.objects.create(item=some_item, user=some_user, activity=ItemHistory.CHECKED_OUT)
The auto_now_add attribute ensures that the timestamp is automatically set when the relationship is created.
You could then actually get rid of the last_checkout and last_activity fields entirely and use something like the following:
class ItemObject(models.Model):
...
def _last_checkout(self):
try:
return self.history.filter(activity=ItemHistory.CHECKED_OUT)[0].timestamp
except IndexError:
return None
last_checkout = property(_last_checkout)
def _last_activity(self):
try:
return self.history.all()[0].timestamp
except IndexError:
return None
last_activity = property(_last_activity)
And, you can then use them as normal:
some_item.last_checkout
Finally, your checkout method is not an override of save so it's not appropriate to call super(ItemObject, self).save(). Just use self.save() instead.

Categories