I need to add tags to my blog posts. Each tag should be available on many posts and also posts can have multiple tags.
How can I change the admin sites so that I can add multiple (existing) tags to a post?
The standard view only lets me add by creating new ones.
model.py
# blog post tags
class Tag(models.Model):
name = models.CharField(max_length=20)
slug = models.SlugField(max_length=40, unique=True)
date_created = models.DateTimeField(default=timezone.now)
class Meta:
ordering = ['name']
def __str__(self):
return self.name
# blog posts
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
last_modified = models.DateTimeField(auto_now=True)
author = models.ForeignKey(User, on_delete=models.CASCADE) # 1 author per post
tags = models.ManyToManyField(Tag, related_name='tags') # n tags per m posts
class Meta:
ordering = ['title']
def __str__(self):
return self.title
Current Admin Site
I know I need to edit my admin.py file in my blog application but everything i tried so far did not work. Is there a recipe for these admin views?
I want to achieve something like this (1st answer - filtered view).
Related
models.py
from django.db import models
from django.contrib.auth.models import User
STATUS = (
(0,"Draft"),
(1,"Publish")
)
class BlogModel(models.Model):
id = models.AutoField(primary_key=True)
blog_title = models.CharField(max_length=200)
blog = models.TextField()
status = models.IntegerField(choices=STATUS, default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-created_at']
def __str__(self):
return f"Blog: {self.blog_title}"
class CommentModel(models.Model):
your_name = models.CharField(max_length=20)
comment_text = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
blog = models.ForeignKey('BlogModel', on_delete=models.CASCADE)
class Meta:
ordering = ['-created_at']
def __str__(self):
return f"Comment by Name: {self.your_name}"
admin.py
from django.contrib import admin
from blog.models import BlogModel,CommentModel
class PostAdmin(admin.ModelAdmin):
list_display = ('blog_title', 'status','created_at','updated_at')
list_filter = ('status',)
search_fields = ('blog_title', 'content',)
admin.site.register(BlogModel, PostAdmin)
admin.site.register(CommentModel)
I created a simple blog post website with comments and I want to create reports and on the admin panel I have to see how to achieve this.
Like how many posts are created and how many have comments and how many post are draft and published
I checked this module but I don't understand how to implement it https://pypi.org/project/django-reports-admin/
You already have most of this, by using PostAdmin. The list_display already shows you how many posts are published/draft, and the change list has filters for that as well.
To show the comment count, simply add that to list_display:
class PostAdmin(admin.ModelAdmin):
list_display = ('blog_title', 'status', 'comment_count', 'created_at', 'updated_at')
def comment_count(self, obj):
return obj.commentmodel_set.count()
comment_count.short_description = 'Comment count'
This thus defines a custom method on the PostAdmin, that displays the comment count as a column, and gives it a user-friendly name as column header.
You can expand this with more statistics if you like. The Django admin is highly customizable.
Note: model names should be in CamelCase, so BlogModel and CommentModel should be Blog and Comment respectively.
I have created a project API in djangorestframework but I want to add a comments feature in it also. I was scratching my head thinking how can I do it but couldn't end up with a solution since I'm a beginner in djangorestframework.
here is my models.py:
class Project(models.Model):
title = models.CharField(max_length=300)
body = models.TextField(max_length=5000)
header_image = models.ImageField(default="default.jpg")
demo = models.URLField(null=True, blank=True)
code = models.URLField(null=True, blank=True)
and here is my serializers.py:
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = "__all__"
and here is my views.py:
#api_view(["GET"])
def getProjects(request):
project = models.Project.objects.all()
serializer = ProjectSerializer(project, many=True)
return Response(serializer.data)
Please help me in showing how can I add a comments section to the project API
note: I don't want the comments API to be a different object instead it should be a nested object in the object of the project
As each project can have several comments, you should implement Comment model and make a FK between these two
models.py
...
class Comment(models.Model):
project = models.ForeignKey('Project', related_name='comments', on_delete=models.CASCADE)
text = models.TextField(null=False, blank=False)
... # Some other field if you want. like created_time, author, ...
Then you can have a nested serializer to get comments with project:
serializers.py
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ('text', ...)
class ProjectSerializer(serializers.ModelSerializer):
comments = CommentSerializer(many=True)
class Meta:
model = Project
fields = (..., 'comments')
I tried to solve the problem and got stuck. The problem is that I have a post that I can follow. My problem is that I don't know how to add a tracking button. Should this be done by url, with a view? Or should it be rather as a method in the model?
My problem is also whether it is properly written in terms of models - using the intermediate model Follower?
Here is Post model and I would like to add followers here. I mean, everybody who is interested, can follow this post.
class Post(models.Model):
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='posts')
title = models.CharField(max_length=255, unique=True)
description = models.TextField(max_length=1024)
followers = models.ManyToManyField(settings.AUTH_USER_MODEL, through='Follower', blank=True)
is_visible = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('posts:post_detail', kwargs={'pk': self.pk})
def number_of_followers(self):
return self.followers.count()
Here is my manager for follower model:
class FollowerManager(models.Manager):
use_for_related_fields = True
def follow(self, user, pk):
post_object = get_object_or_404(Post, pk=pk)
if user.is_authenticated():
if user in post_object.followers.all():
Follower.objects.filter(post=post_object, user=user).delete()
else:
Follower.objects.create(post=post_object, user=user)
Here is Follower model:
class Follower(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
objects = FollowerManager()
Interactions between a user's browser and the database can only be done via a URL and a view. That view might call a model method, but there is no possible way for the browser to call that method directly.
(Also I don't understand what you're doing in the manager. Why are you deleting followers if the user is authenticated? Note that will always be true, so the followers will always be deleted.)
I was wondering if it's possible to arrange pictures uploaded to wagtail into galleries based on their tags.
I have an album app, and its models.py contains :
from django.db import models
from wagtail.wagtailcore.models import Page
# Create your models here.
class Category(Page):
name = models.CharField(max_length=250)
slug = models.SlugField()
image = models.ImageField()
parent = models.ForeignKey('self', blank=True, null=True, related_name='children')
def __str__(self):
return self.name
class Post(Page):
title = models.CharField(max_length=120)
category = models.ForeignKey('Category', null=True, blank=True)
publish = models.DateField(auto_now=False, auto_now_add=False, )
slug = models.SlugField(unique=True)
Images use django-taggit for its tags so you can query them easily.
from wagtail.wagtailimages import get_image_model
# Somewhere in your code
image_class = get_image_model()
images = image_class.objects.filter(tags__name='the_slug')
On a side note, the slug field on your Category page in your snippet might shadow the slug field of the base Page model so you might want to be careful with that.
From the last seven days I am trying to build a blog using django and I figured out the model for my blog as follows
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
created_at = models.DateTimeField('created date', auto_now_add=True, auto_now=False)
updated_at = models.DateTimeField('updated date', auto_now_add=False, auto_now=True)
def __str__(self):
return self.title
class Author(models.Model):
name = models.CharField(max_length=150)
email = models.EmailField(blank=True)
bio = models.TextField()
#This line define many author can have a post
#but I want manypost can only have single author.
#in my view to accomplish this i need to define author in Post class
#on defining author=ForeignKey(Author) in post, It throws an error Author is not defined
post = models.ForeignKey(Post)
def __str__(self):
return self.author
class Category(models.Model):
cat_name = models.CharField(max_length=200)
post = models.ManyToManyField(Post)
def __str__(self):
return self.cat_name
The thing that I am so much confused is the relation between the Post, Categories, Author and Tag.
Relation What I wanted to set is
author can have many posts, A post can have only single author
categories can have many posts, A post can have many categories
a tag can have many posts a post can have many tags
But the models that I am created above is not working as I expected(I am so confused).
when I put the author field in Post Class, so that i would be a relation like, an author can have many posts, but I got the error Author is not defined.(as I know the interpreter run code from top to bottom). How do I accomplish
You have two options:
Change Author and Post position, thus Page can see Post definition.
Use Lazy call as: author= models.ForeignKey("Author")
In this way, Django will wait until all models load then resolve the dependencies.
Try model structure syntax:
class Author(models.Model):
name = models.CharField(max_length=150)
email = models.EmailField(blank=True)
bio = models.TextField()
def __str__(self):
return self.author
class Post(models.Model):
author = models.ForeignKey(Author)
title = models.CharField(max_length=200)
body = models.TextField()
created_at = models.DateTimeField('created date', auto_now_add=True, auto_now=False)
updated_at = models.DateTimeField('updated date', auto_now_add=False, auto_now=True)
def __str__(self):
return self.title
class Category(models.Model):
cat_name = models.CharField(max_length=200)
post = models.ManyToManyField(Post)
def __str__(self):
return self.cat_name
class Tag(models.Model):
tag_name = models.CharField(max_length=200)
post = models.ManyToManyField(Post)
def __str__(self):
return self.tag_name
This will solve your three requirements:
1.) Author can have many posts because I set the Post Model into one-to-many field
2.) Categories can have many posts vice versa (This is already set according to your code)
3.) Tag can have many posts vice versa (Very similar to your already made Category Model where I made the field many-to-many between the two)
The reason why you got an error is because you made your author to post relation to many-to-one (many authors in one post) according to your model structure
Now to test it simply migrate all these changes and quickly test it in your admin page
author can have many posts, A post can have only single author
Post model should have a ForeignKey pointing to Author.
class Post(...):
author = models.ForeignKey('Author')
categories can have many posts, A post can have many categories
Post model should have a ManyToManyField pointing to Category.
class Post(...):
category = models.ManyToManyField('Category')
a tag can have many posts a post can have many tags
Same as number 2.