As title says I was trying to sort a list of posts using the django order_by method and since the field I used was later added to the list (The field was not created inside the model) it failed.
Is there anything I can do about it other than adding the field to the model which is something I really don't wanna do?
Here is the model code
class post(models.Model):
title = models.CharField(max_length=236)
content = models.TextField()
post_board = models.ForeignKey(board, on_delete=models.CASCADE)
author = models.ForeignKey(User, on_delete=models.CASCADE)
release_date = models.DateField(auto_now_add=True)
views = models.IntegerField(default=0)
def __str__(self):
return self.title
The function that adds the extra field:
def forumdisplay(request, boardslug=None):
context = { 'board': None }
if boardslug:
context['board'] = board.objects.all().filter(slug=boardslug).first()
if context['board']:
context['posts'] = post.objects.all().filter(post_board=context['board'])
for eachpost in context['posts']:
eachpost.reply_count = len(reply.objects.all().filter(reply_to=eachpost))
eachpost.last_activity = eachpost.release_date
if eachpost.reply_count:
eachpost.last_activity = reply.objects.all().filter(reply_to=eachpost).order_by('release_date').first().release_date
context['posts'] = context['posts'].order_by('last_activity')
alter_posts(context['posts'])
else:
pass
return render(request, "board/forumdisplay.html", context)
The error I got:
Request Method: GET
Request URL: http://127.0.0.1:8000/forumdisplay/news/
Django Version: 3.0.4
Exception Type: FieldError
Exception Value:
Cannot resolve keyword 'last_activity' into field. Choices are: author, author_id, content, id, post_board, post_board_id, release_date, reply, title, views```
You can't.
order_by that you are trying to use is actually will be translated into SQL command to be executed on database, and while database has no column called last_activity so you can't apply this function to it.
what is the problem to add a new column to your DB and make it nullable?
Related
I understand that you can't directly use icontains on a foreign key when searching but I haven't found a solution yet.
Here is my search view in views.py (I have imported every model needed):
def search(request):
# if the user actually fills up the form
if request.method == "POST":
searched = request.POST['searched']
# author__icontains part is not working
posts = Post.objects.filter(Q(title__icontains=searched) | Q(author__author__icontains=searched))
return render(request, 'blog/search.html', {'searched': searched, 'posts': posts})
else:
return render(request, 'blog/search.html', {})
Here is my model in model.py:
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
Mainly, this is not working:
posts = Post.objects.filter(Q(title__icontains=searched) | Q(author__author__icontains=searched))
The error is Related Field got invalid lookup: icontains
author is a User object. Therefore you should work with username, or first_name, or some other field. Likely author is also the value of a related_name=… [Django-doc] that thus makes a LEFT OUTER JOIN on another table, and thus would work on the primary key(s) of that table.
You thus filter with:
def search(request):
# if the user actually fills up the form
if request.method == 'POST':
searched = request.POST['searched']
# author__icontains part is not working
posts = Post.objects.filter(
Q(title__icontains=searched) |
Q(author__username__icontains=searched)
)
return render(request, 'blog/search.html', {'searched': searched, 'posts': posts})
return render(request, 'blog/search.html')
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
Note: Searching is usually done through a GET rquest, since that means the query is stored in the querystring and thus the URL. This makes it convenient to for example share the URL with the query to someone else, or bookmark the result. POST requests are usually used for state-changing actions, or for requests with sensitive data.
This problem is caused by Django's inability to handle foreign keys with multiple values for a single field. The reason for this limitation is that Django doesn't know how to resolve these conflicts, so it simply ignores them. In your case, since there are two fields in your model that match the search criteria, Django will ignore both of those results and display an empty list.
To fix this issue, we need to add a new attribute to our model called "icontains" which would contain the value of the other field. Then, we'll set this attribute as a default value for the "author" field when querying from the database. Here is what your model should look like now:
class Post(models.Model): title = models.CharField(max_length=100) content = models.TextField() date_posted = models.DateTimeField(default=timezone.now) author = models.ForeignKey(User, on_delete=models.CASCADE) icontains = models.CharField(max_length=100, null=True, blank=True) def __str__(self): return self.title def get_absolute_url(self): return reverse('post-detail', kwargs=dict(pk=self.pk))
With this change, the code will work properly.
For more information about this limitation, see the Django documentation here: https://docs.djangoproject.com/en/1.9/topics/db/queries/#lookups-that-span-relationships
I'm trying to do a search for a query in Django, the icontains lookup works for the title(CharField) but not for the content(TextField). I want to search if the query exists in the title or content of a post.
Model that I'm using to test queries: (models.py)
class BlogPost(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=120, blank=True)
content = models.TextField(blank=True)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '{} - {}'.format(self.title, self.user.username)
This is the code: (views.py)
from django.db.models import Q
...
class BlogPostAPIView(mixins.CreateModelMixin, generics.ListAPIView):
...
def get_queryset(self):
qs = BlogPost.objects.all()
query = self.request.GET.get('q')
if query is not None:
qs = qs.filter(Q(title__icontains=query) | Q(content__icontains=query)).distinct()
return qs
This is the error I get when making a query:
Exception Type: FieldError
Exception Value: Unsupported lookup 'icontains' for TextField or join on the field not permitted.
you can use
results = Cancer.objects.filter(abstract__contains='cancer').values_list('title', 'document_id')
str(results.query)
'SELECT "patents_cancer"."title", "patents_cancer"."document_id" FROM "patents_cancer" WHERE "patents_cancer"."abstract"::text LIKE %cancer%'
or
you can use Search for TextField
like Entry.objects.filter(body_text__search='Cheese')
https://docs.djangoproject.com/en/2.1/ref/contrib/postgres/search/
Change your field to a CharField. As explained in a comment, you're using SQLite. SQLite doesn't pose any length restrictions on character fields.
You have two choices to solve this
1. Change TextField to CharField. This will compromise your text storage
2. Use DB such as MYSQL , PostgreSQL etc
I'm doing a Django project (kind of social network) and want to have a page where I can see all my posts, which I did.
I allways get the error: no such column: uploaded_by
in models.py
from django.db import models
from django.contrib.auth.models import User
class ContentItem(models.Model):
upload_date = models.DateTimeField(auto_now=True)
title = models.CharField(max_length=100, default='no title')
description = models.CharField(max_length=400, default='no description')
image = models.ImageField(upload_to='image_board/posts/', default='null')
uploaded_by = models.ForeignKey(User, default='0')
def __str__(self):
return self.title
in views.py
def view_my_favorites(request):
all_posts = ContentItem.objects.raw('SELECT * FROM image_board_ContentItem WHERE uploaded_by = request.user.username')
template = loader.get_template('favorites.html')
context = {
'all_posts': all_posts,
}
return HttpResponse(template.render(context, request))
I want to get the user name of the user who is loged in, how can i whrite this in the sql query?
Thaks guys :)
Your actual issue is probably caused by neglecting to make and run migrations after adding the uploaded_by field.
But there are a huge number of other things wrong here.
Firstly, you are comparing the uploaded_by column with a non-existent column, request.user.username. You need to use the actual value of that variable.
Secondly, you are comparing a foreign key - uploaded_by - with a string, username. These will never match.
Thirdly, you are using a raw query. There is absolutely no need to do that here.
Your query is trivial to express in the Django query syntax. You should do:
all_posts = ContentItem.filter(uploaded_by=request.user)
or even simpler:
all_posts = request.user.contentitem_set.all()
please help to understand.
I have the next models :
class TagsList(models.Model):
tags_list = models.CharField(max_length=30)
def __str__(self):
return self.tags_list
class Blog(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
pub_date = models.DateTimeField(auto_now_add=True)
tags = models.ManyToManyField(TagsList)
how i can get related tags by object (in my case object with post_id)?
It's my view file :
def single(request, post_id):
object_post = Blog.objects.get(id=post_id)
tags = TagsList.objects.all()
content = {
'object_post': object_post,
'tags': tags,
}
return render(request, 'single.html', content)
I tried all cases, but how to include to content exactly tags which are related to this object, don't know.
Thanks all, for the help.
P.S. Using django 1.11
initial answer from comments:
In a many-to-many relation you can access the related objects, try this in def single:
tags=object_post.tags.all()
I want to get a specific Video object and then find all of the Rating objects that are associated with it using ForeignKey reverse lookup as described in the docs.
I have models:
class Video(models.Model):
...
rating_int = models.IntegerField(default=1, choices=CHOICES, name='rating_int')
def __str__(self):
return self.title
class Rating(models.Model):
video = models.ForeignKey('Video', related_name='video', null=True)
and views:
def video_ratings(request):
vid_rate = Video.objects.get(pk=1)
ratings_of_video = vid_rate.rating_set.all()
context = {
'vid_rate': vid_rate, 'ratings_video': ratings_of_video
}
return HttpResponse(template.render(context, request))
When I try to run this I get an error 'Video' object has no attribute 'rating_set'
But when i read the django docs it tells me when you do a reverse lookup you need to use this _set.all() command. I am not sure what is missing here.
You have specified related_name in your foreign key loopkup. so rating_set should not work now.
You can lookup like
ratings_of_video = vid_rate.video.all()
A better naming convention will be to use ratings in your related_name
class Rating(models.Model):
video = models.ForeignKey('Video', related_name='ratings', null=True)
and then query like
ratings_of_video = vid_rate.ratings.all()