I am new to Django and trying to pass an author's name to a view and filter out quote objects based on the author's name. here are the codes:
models.py
class Author(models.Model):
author_name = models.CharField(max_length=50, default='unknown')
author_info = models.TextField(max_length=1000)
class Quote(models.Model):
author = models.ForeignKey(Author)
quote = models.TextField(max_length=500)
category= models.ForeignKey(Category)
pub_date = models.DateTimeField('date published')
urls.py:
url(r'^quotes/(?P<name>\w+)/$', 'quotes.views.quotesbyauthor'),
views.py
def quotesbyauthor(request, name):
aquotelist = Quote.objects.filter(author__exact = name)
return render_to_response(quotes_by_author.html, {'aquotelist': aquotelist })
However I get this error when I try to get http://127.0.0.1:8000/quotes/you/
('you' is a test author object, already created)
ValueError at /quotes/you/
invalid literal for int() with base 10: 'you'
Request Method: GET
Request URL: http://127.0.0.1:8000/quotes/you/
Django Version: 1.3.1
Exception Type: ValueError
Exception Value:
invalid literal for int() with base 10: 'you'
Exception Location: /home/qliq/djenv/lib/python2.6/site-packages/django/db/models/fields/__init__.py in get_prep_value, line 479
Python Executable: /home/qliq/djenv/bin/python
Python Version: 2.6.6
Python Path:
['/home/qliq/djenv/quoteapp',
'/home/qliq/djenv/lib/python2.6/site-packages/distribute-0.6.10-py2.6.egg',
'/home/qliq/djenv/lib/python2.6/site-packages/pip-0.7.2-py2.6.egg',
'/home/qliq/djenv/lib/python2.6',
'/home/qliq/djenv/lib/python2.6/plat-linux2',
'/home/qliq/djenv/lib/python2.6/lib-tk',
'/home/qliq/djenv/lib/python2.6/lib-old',
'/home/qliq/djenv/lib/python2.6/lib-dynload',
'/usr/lib/python2.6',
'/usr/lib/python2.6/plat-linux2',
'/usr/lib/python2.6/lib-tk',
'/home/qliq/djenv/lib/python2.6/site-packages']
I appreciate your help to resolve this.
You want to search on the author's author_name field, not the id.
Quote.objects.filter(author__author_name=name)
With your current search, author__exact, Django expects name to be the id of the author, so gives an error because you is not an integer.
aquotelist = Quote.objects.filter(author__author_name__exact = name)
Try changing the corresponding line to the above. The way you have it now, you are matching author to the given name, but author is probably considered by its ID here, definitely not by its author_name. The format is as follows:
Quote.objects.filter([model]__[field]__exact = [whatever])
I have faced and solved similar issue,
focus on attribute : author = models.ForeignKey(Author)
django expect that you pass an Instance of Author class to the author field. When you search django want to get a id (a integer number of this Instance):
so to get :
aquotelist = Quote.objects.filter(author__exact = name)
you have to start by :
create obj_Author = Author.objects.get(author_name = name)
aquotelist = Quote.objects.get(author__exact = obj_Author.id)
PS: ( I used get() in my example but if you expect to get multiple record, you can you use filter() and modify something. but main point is that because you work with a "ForeignKey field" so you need to give it a id like obj_Author.id. )
I think you should reset your migrate , you can see this link :
https://stackoverflow.com/a/54768217/9533909
i hope that help you.
I faced this issue and I figured out that I made records in the DB table that in your case is (Quote) before making the foreign key relationship with (Author) then after making the foreign key relationship Django doesn't know what to do to handle the old data in Quote model (to which records in Author should old records be assigned to)
--> The simplest solution is to:
delete your old Quote records: Quote.objects.all().delete inside your shell
recreate and reassign its new records correctly
makemigrations, migrate and runserver ... done
This will fix your problem permanently ::go to your directory
C:\python 37\Lib\site-packages\django\db\models\fields
and edit the file __init__.py and edit line 1807; replace
return int(value)
with
return int()
So just delete the argument value then your program will except all field references.
Related
I am relatively new to Python / Django.
I am trying to create a relationship between food items and the category (name)
they belong:
class Category(models.Model):
options=(
('vegetable','vegetable'),
('fruit','fruit'),
('carbs','carbs'),
('fish','fish'),
('meat', 'meat'),
('sweet', 'sweet'),
('dairy', 'dairy'),
)
name=models.CharField(max_length=10,choices=options,unique=True)
def __str__(self):
return self.name
class Fooditem(models.Model):
name = models.CharField(max_length=50)
category = models.ForeignKey(Category,on_delete=models.CASCADE)
The code above throws error when running migrate:
ValueError: invalid literal for int() with base 10: 'vegetable'
I created some items in the database, is it the reason?
What is the best way to solve this problem?
Thank you,
D
It would fix it, but you may have some unexpected results.
category = models.ForeignKey(Category,on_delete=models.CASCADE)
will be an id pointing to the other model.
You can make name the primary key by changing it to the following:
name=models.CharField(max_length=10,choices=options,unique=True,primary_key=True)
Also reviewing https://docs.djangoproject.com/en/3.1/ref/models/fields/#choices more closely may help you with your options down the road. It will programming easier to define as costants and follow thier syntaxing
I would realy recommend u to do it this way. if there is something that is unclear just let me know
class Category(models.TextChoices):
vegetable='vegetable'
fruit='fruit'
carbs='carbs'
fish='fish'
meat='meat'
sweet='sweet'
dairy='dairy'
class Fooditem(models.Model):
name = models.CharField(max_length=50)
category = models.CharField(max_length=20, choices=Category.choices)```
I was using django-hitcont to count the views on my Post model. I am trying to get the most viewed post in my ListView using this query objects.order_by('hit_count_generic__hits') and it is working fine on SQLite but on PostgreSQL, it is giving me this error :
django.db.utils.ProgrammingError: operator does not exist: integer = text LINE 1: ...R JOIN "hitcount_hit_count" ON ("posts_post"."id" = "hitcoun....
models.py
class Post(models.Model, HitCountMixin):
author = models.ForeignKey(User, related_name='authors', on_delete=models.CASCADE)
title = models.CharField('Post Title', max_length = 150)
description = models.TextField('Description', max_length=1000, blank = True)
date_posted = models.DateTimeField('Date posted', default = timezone.now)
date_modifed = models.DateTimeField('Date last modified', default = timezone.now)
document = models.FileField('Document of Post', upload_to='documents', \
validators=[FileExtensionValidator(allowed_extensions = ['pdf', 'docx']), validate_document_size] \
)
hit_count_generic = GenericRelation(
HitCount,
object_id_field='object_pk',
related_query_name='hit_count_generic_relation'
)
views.py
queryset = Post.objects.order_by('hit_count_generic__hits')
I found this issue on Github related to the problem, but I am still not able to figure out the mentioned workaround.
When comparing different types (in this example integer and text), equals operator throws this exception. To fix that, convert HitCount model pk field to integer and you are good to go. To do that, you need to create and apply migration operation. Django is a really good framework to handle this kind of operations. You just need to check values are not null and are "convertable" to integer. Just change the field type and run two commands below.
python manage.py makemigrations
python manage.py migrate
Before updating your model, I highly recommend you to take a backup in case of failure. This is not an easy operation but you can follow the these links to understand what is going on during this the process.
migrations dump and restore initial data
If you don't care the data on table, just drop table and create a brand new migration file and recreate table.
I am going through Tango with Django and I can't solve this excercise.
I get django.db.utils.IntegrityError: UNIQUE constraint failed: rango_category.name error. This is after I try to implement views attribute to Category object. This is a excerpt from my database population script. I though maybe that I should makemigrations and then migrate to update models for DB. However, this didn't help.
cats = {
'Python' : {'pages': python_pages, 'views':128},
'Django': {'pages': django_pages, 'views':128},
"Other Frameworks": {'pages':other_pages, 'views':128},
}
for cat, cat_data in cats.items():
c = add_cat(cat, cat_data['views'])
for p in cat_data["pages"]:
add_page(c, p['title'], p['url'])
for c in Category.objects.all():
for p in Page.objects.filter(category=c):
print("- {0} - {1}".format(str(c), str(p)))
def add_cat(name, views):
c = Category.objects.get_or_create(name=name, views=views)[0]
c.views=views
c.save()
return c
Adding Category model:
class Category(models.Model):
name = models.CharField(max_length=128, unique=True)
views = models.IntegerField(default=0)
class Meta:
verbose_name_plural = 'Categories'
def __str__(self):
return self.name
You got the error because unique = True in name = models.CharField(max_length=128, unique=True) means that Django will raise constraint errror UNIQUE constraint failed in case you trying to save a new instance with the same name value; A violation of the unique constraint
get_or_create doesn't work because views=views that may be different even though name equals name
When you create or get your instance, you can do so with only the name field
def add_cat(name, views):
c = Category.objects.get_or_create(name=name, views=views)[0]
c.views=views
c.save()
return c
As mentioned in comments, the error is caused by violation of the unique constraint on Category.name. The reason that this is happening might not be completely obvious, however. When you call Category.objects.get_or_create, you are asking django to look for an object with both the given name and the given number of views. If one is not found, then django tries to create one, which violates the unique constraint if there is already a Category of the same name, but with a different number of views. Depending on desired behavior, you can fix by either:
remove unique constraint altogether
change unique constraint to a unique_together constraint
change the model reference to first get or create by name, then set (or modify) the views attribute (don't forget to save)
Trying to get to the bottom of this error. Several SO questions on the subject and the answers range from: deleting previous migrations, setting default value in the model for the field, or using a GenericForeignKey. None have resolved my issue thus far.
I am fairly certain the issue is related to ForeignKey and have read it uses int() by default even if the field is CharField.
Here is the field in question in the model I am trying use:
product_code = models.ForeignKey(Products, null=False)
Here is the field in the parent model it is referring to (Products):
code = models.CharField(unique=True, max_length=16)
And here is the query where the issue is occurring:
# returns 'A_17'
product_code = Products.objects.get(id=data['product_id']).code
# error triggered here:
print(ProductPositions.objects.filter(product_code=product_code))
# ValueError: invalid literal for int() with base 10: 'A_17'
So it appears to be string from end-to-end, but I guess with the ForeignKey "defaulting" to integer or something the issue is related to that. Not sure how to override that as something like default='' doesn't work.
Not sure how to clear up the issue so thanks for the feedback.
You are using the actually code to do the lookup and it is anticipating the primary key. You can alter this two ways
Using the primary key:
product_code = Products.objects.get(id=data['product_id'])
print(ProductPositions.objects.filter(product_code=product_code.pk))
Or using the code (the __ will tell Django to refer the field through the foreign key):
product_code = Products.objects.get(id=data['product_id']).code
print(ProductPositions.objects.filter(product_code__code=product_code))
I'm learning Django.
I have two models as follows:
class IdentificationAddress(models.Model):
id_ident_address = models.AutoField(primary_key=True)
ident = models.ForeignKey('Ident', models.DO_NOTHING, db_column='ident')
address = models.TextField()
time = models.DateTimeField()
class Meta:
managed = False
db_table = 'identification_address'
class IdentC(models.Model):
id_ident = models.AutoField(primary_key=True)
ident = models.TextField(unique=True)
name = models.TextField()
class Meta:
managed = False
db_table = 'ident'
I am using the Django debugger:
python manage.py shell
and import the model
from invent.models import IdentC as identity
from invent.models import IdentificationAddress as ident_Address
I can access the name of a specific identity
indentity.objects.filter(ident='00LD').values('name')
it returns
<QuerySet [{'name': u'Joss'}]>
Then I can access information of a specific address:
ident_Address.objects.filter(address='LOC23').values().last()
it returns
{'times': u'{"2017-07-16"}', u'ident_id': u'00LD', 'address': u'LOC23', 'id_ident_address': 217}
but I get an error when I try to use any identity
ident_Address.objects.filter(ident='00LD').values()
or
ident_Address.objects.filter(ident_id='00LD').values()
error:
ValueError: invalid literal for int() with base 10: '00LD'
If I try this in postgres
SELECT * FROM identification_address WHERE ident= '00LD'
I don't have any problem.
I appreciate any help.
Thank you in advance
NOTE: For the sake of clarity, I've changed the name of the Ident model to IdentC
You try to match '00LD' with the field id of Ident.
Or in your first example you wrote :
indentity.objects.filter(ident='00LD').values('name')
'00LD' match with ident field of Ident
So you can filter like this :
ident_Address.objects.filter(ident__ident='00LD').values()
First ident represent your model, and the second one, the field of Ident.
If you want to filter ident_Address by Ident name :
ident_Address.objects.filter(ident__name='Joss').values()
In Django, when you want to access some field in ForeignKey table, you should use __ (Double underscore). For your case, it will be
ident_Address.objects.filter(ident__id_ident='00LD')
Thanks guys.
Sorry #Exprator I'm learning how to use the answer field, as well.
So I started debugging how Django queries are translated to SQL queries. Then I found the solution:
ident_Address.objects.filter(ident__id_ident__iexact='00LD').values()
Where first ident means field ident in IdentificationAddress model and id_ident field in identC model