I've created Comment section. The main goal is that only registered users can post comments and only from their usernames.
For now, I have a problem from who (username) the post is posting. On screenshot, you can see, that I can choose to post comment from user:JOHUA, but I'm currently logged in from user:JOHN
I need to set permission for user to post comment only from his username (maybe I should remove username variable in models.py, forms.py and admin.py and to set it by default like user:username, or maybe you know how to remove other usernames from Username column, so register user can only choose his username.
I have been puzzling over this problem for a long time, so definitely need community help!
HERE IS SOME CODE:
models.py
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
username = models.ForeignKey(User, on_delete=models.CASCADE)
email = models.EmailField()
body = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=False)
class Meta:
ordering = ['created_on']
def __str__(self):
return 'Comment {} by {}'.format(self.body, self.username)
forms.py
from .models import Comment
from django import forms
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['username', 'email', 'body']
admin.py
from django.contrib import admin
from .models import Post, Category, Comment
class CategoryAdmin(admin.ModelAdmin):
pass
#admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
list_display = ('username', 'body', 'post', 'created_on', 'active')
list_filter = ('active', 'created_on')
search_fields = ('username', 'email', 'body')
actions = ['approve_comments']
def approve_comments(self, request, queryset):
queryset.update(active=True)
admin.site.register(Post)
admin.site.register(Category, CategoryAdmin)
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 tried to make search field to search by author in the admin panel but i got an error
Related Field got invalid lookup: icontains
i follow the documentation and other stackoverflow question but it doesn't work
#model.py
from django.contrib.auth import get_user_model
User = get_user_model()
class Author(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
def __str__(self):
return str(self.user)
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=256)
content = models.TextField(verbose_name='content')
date_published = models.DateTimeField(auto_now_add=True)
date_edited = models.DateTimeField(auto_now=True)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
thumbnail = models.ImageField(blank=True)
def __str__(self):
return self.title
#admin.py
from django.contrib import admin
from .models import Post, Author,
class PostAdmin(admin.ModelAdmin):
list_display = ['title',
'date_published',
'date_edited',
'author', ]
search_fields = ['title',
'author__user',]
admin.site.register(Post, PostAdmin)
admin.site.register(Author)
it works when i changed the search_field[1] to author__id, but since it only accept id, it can't get the username. any idea how to solve it? should i make custom user model?
I'm learning django and I made the tutorial on django site. I thought that I could link user to poll that he created but I'm struggling with it. When I'm logged in and creating a poll I can't see user name. In database column author_id has value null. I would appreciate every help.
Here is my code
from django.db import models
from django.utils import timezone
import datetime
from django.contrib import auth
# Create your models here.
User = auth.get_user_model()
class Question(models.Model):
question_text = models.CharField(max_length=200)
author = models.ForeignKey(User, on_delete=models.CASCADE, null=False)
def __str__(self):
return self.question_text
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
class User(auth.models.User, auth.models.PermissionsMixin):
def __str__(self):
return "#{}".format(self.username)
forms.py:
class UserCreateForm(UserCreationForm):
class Meta:
fields = ('username', 'email', 'password1', 'password2')
model = get_user_model()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].label = 'Display Name'
self.fields['email'].label = 'Email Address'
class CreatePollForm(forms.ModelForm):
class Meta:
model = Question
fields = ('question_text',)
and views.py
class CreatePoll(LoginRequiredMixin, generic.CreateView):
form_class = forms.CreatePollForm
success_url = reverse_lazy('pollapp:index')
template_name = 'polls/createPoll.html'
Since your CreatePollForm only assigns the question_text field, you need to assign the author in code. A CreateView is a FormView which does the saving of the form in its form_valid() method. So in your CreateView, you want to override that method:
# in class CreatePoll
def form_valid(self, form):
question = form.save(commit=False) # fetch the new question, don't save
question.author = self.request.user # assign the user
question.save() # now save
return super().form_valid(form)
It isn't clear how you could end up with a null value for the author_id, that should have raised an IntegrityError. Are you sure you ran makemigrations and migrate in the current state?
I am using rest-auth registration api for user registration. I have some extra fields in the UserProfile model.
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
org_id = models.CharField(max_length=100, default='')
is_teacher = models.BooleanField(blank=True, default=False)
def __str__(self):
return self.user.username
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
The UserProfile model is shown above. How can I add these fields to rest-auth regestration api endpoint and save the data to database.
I found an answer for myself
The serializers can be written as
from rest_framework import serializers
from rest_auth.registration.serializers import RegisterSerializer
from .models import UserProfile
class RegistrationSerializer(RegisterSerializer):
first_name = serializers.CharField(required=False)
last_name = serializers.CharField(required=False)
personal_id = serializers.CharField(required=True)
def custom_signup(self, request, user):
user.first_name = self.validated_data.get('first_name', '')
user.last_name = self.validated_data.get('last_name', '')
user.userprofile.personal_id = self.validated_data.get(
'personal_id', '')
user.save(update_fields=['first_name', 'last_name'])
user.userprofile.save(update_fields=['org_id'])
I didnt add the is_teacher because its optional.
In views.py extend the RegisterView of the rest_auth.regeistration.views to pass this data and its done.
class RegistrationView(RegisterView):
serializer_class = RegistrationSerializer
And finally add a url and pass RegisterView.as_view().
I made a registration page in django but the problem is that it should not accept one email address for multiple accounts. How to resolve this issue? If you need code then let me know.
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} Profile'
forms.py
class UserRegisterForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username','email','password1','password2']
No need of entering email in forms , User model already contains a email column
your registration form should look like this
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class SignUpForm(UserCreationForm):
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2')
and you can simply use this line in models.py to make email Unique
User._meta.get_field('email')._unique = True