Django - Get values from ManyToManyField which is foreing key - python

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()

Related

Multiple search with django foreign key (Related Field got invalid lookup: icontains)

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

Cannot resolve keyword 'last_activity' into field

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?

Django admin shows Post object in lieu of title

Really new to Django so bear with me :)
I am running into an issue to display the posts titles in the Django admin.
I have tried both in Python 3
class Post(models.Model):
title = models.TextField(max_length=100)
text = models.TextField(max_length=10000)
tags = models.TextField(max_length=300)
comments = models.TextField(max_length=400)
def __str__(self):
return self.title
and Python 2
class Post(models.Model):
title = models.TextField(max_length=100)
text = models.TextField(max_length=10000)
tags = models.TextField(max_length=300)
comments = models.TextField(max_length=400)
def __unicode__(self):
return self.title
but unfortunately in the Django admin I see
"Post object "in the list of posts
Thanks in advance for your help.
Maybe you can try this:
from django.utils.encoding import python_2_unicode_compatible
#python_2_unicode_compatible
class Post(models.Model):
title = models.CharField(max_length=255)
text = models.TextField(max_length=10000)
tags = models.TextField(max_length=300)
comments = models.TextField(max_length=400)
def __str__(self):
return self.title
For those who might come here after me, you'd have to add this method inside the model class.
def __str__(self):
return self.title
Make sure it's indented right or else it might not work.
Add your post models to the administration site. Edit the admin.py file of your app and make it look like this:
from django.contrib import admin
from .models import Post
admin.site.register(Post)
The admin has many hooks for customization check documentation
There is no way to have Django return, say, a MyPerson object whenever you query for Person objects. A queryset for Person objects will return those types of objects. The whole point of proxy objects is that code relying on the original Person will use those and your own code can use the extensions you included (that no other code is relying on anyway
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
Know more
For those who come after, make sure post is in lowercase.
And after which make migrations again.
make sure name='post' not 'Post'...
migrations.AlterModelOptions(
name='post',

Django no such column ForeignKey

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()

Is it possible to sort elements in a ToManyField attribute using TastyPie?

I have a REST API using Django Tastypie. Given the following code
The models
class BlogPost(models.Model):
# class body omitted, it has a content and an author
class Comment(models.Model):
blog_post = models.ForeignKey(BlogPost, related_name="comments")
published = models.DateTimeField()
# rest of class omitted
The resources
class CommentResource:
# omitted
class BlogPostResource(ModelResource):
comments = fields.ToManyField("resources.CommentResource",
attribute="comments")
When I ask for a blogpost I get something like:
GET: api/blogpost/4/
{
'content' : "....",
'author' : "....",
'comments' : ['api/comment/4/', 'api/comment/5']
}
However, the comments are not necessarily sorted by any field. I would like to make sure they are sorted by a specific key (published)
Is there any way to achieve this?
I managed to solve the issue by changing the field in BlogPostResource to the following:
class BlogPostResource(ModelResource):
comments = fields.ToManyField("resources.CommentResource",
attribute=lambda bundle: bundle.obj.comments.all().order_by("published"))
You could also try adding an ordering in the actual Comment Model (not in the tastypie Comment ModelResource):
class Comment(models.Model):
blog_post = models.ForeignKey(BlogPost, related_name="comments")
published = models.DateTimeField()
class Meta:
ordering = ['published']

Categories

Resources