order by method is not working on queryset - django

order by not working on queryset no working at all and i dont know where is the mistake seems everything is okay !
views.py
class PostDetailView(DetailView):
model = Post
template_name = 'detail.html'
#context_object_name = 'post'
#form_class = CommentForm
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
post_comments = Comment.objects.filter(post=self.get_object()).order_by('-date_added')
data['comments'] = post_comments
if self.request.user.is_authenticated:
data['comment_form'] = CommentForm(instance=self.request.user)
return data
def post(self, request, slug, *args, **kwargs):
new_comment = Comment(comment=request.POST.get('comment'),
name = self.request.user,
post = self.get_object())
new_comment.save()
return redirect('core:detail', slug=slug)
models.py
class Comment(models.Model):
post = models.ForeignKey(Post, related_name='comments', on_delete=models.CASCADE)
name = models.ForeignKey(User, on_delete=models.CASCADE)
comment = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.comment

Related

how can i create a cycle of comments and replies?

I wonder how can I make a cycle of comments and replies :
I wanted to make a replyable comment but replies also need to be replyable to make a better communication but I'm just a student and don't have much experience
here is my models :
class Comment(models.Model):
#comments model
post = models.ForeignKey(Post, on_delete=models.CASCADE)
text = models.CharField(max_length=300)
user = models.ForeignKey(get_user_model(),on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
class Meta():
verbose_name_plural = 'Comments'
ordering = ['date']
def __str__(self):
return self.test[:50]
class Reply(models.Model):
#replying to comments
comment = models.ForeignKey(Comment,on_delete=models.CASCADE)
text = models.CharField(max_length=300)
user = models.ForeignKey(get_user_model(),on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
class Meta():
verbose_name_plural = 'Replies'
ordering = ['date']
def __str__(self):
return self.text[:50]
problem is that if i use this models i have to make a new model for every reply and it's not in cycle.
also I tried to check if replyable comment works or not and i got a problem with view:
I couldn't add both forms(comment, reply) in the same get_context_data()
class PostDetailView(FormView, DetailView):
#detail page of items
template_name = 'pages/post_detail.html'
model = Post
form_class = CommentForm, ReplyForm
def get_context_data(self, **kwargs):
context = super(PostDetailView, self).get_context_data(**kwargs)
context['form'] = self.get_form()
return context
def post(self,request, *args, **kwargs):
form = CommentForm(request.POST)
if form.is_valid():
form_instance = form.save(commit=False)
form_instance.user = self.request.user
form_instance.post = self.get_object()
form_instance.save()
return HttpResponseRedirect(self.get_success_url())
else:
super().is_invalid(form)
def get_success_url(self):
return reverse('pages:post_detail',args=(self.kwargs['pk'],))
how can i fix views and make comments and replies both replyable

How do I restrict access in django?

I have an application in which all users, after registration, can publish articles, how can I make it so that only those who have the rights for this can publish (something like ordinary users and moderators / editors and how to grant these rights. Below is the attached code:
models.py/blogapp
class Post(models.Model):
title = models.CharField(verbose_name=("Заголовок"), max_length=200)
author = models.ForeignKey(User, on_delete=models.CASCADE)
header_image = models.ImageField(verbose_name=("Заглавное Изображение"), null=True, blank=True, upload_to="images/" )
body = RichTextField(verbose_name=("Тело Статьи"), blank=True, null=True)
#body = models.TextField(blank=True, null=True)
post_date = models.DateTimeField(auto_now_add=True)
category = models.CharField(verbose_name=("Категория"), max_length=200)
snippet = models.CharField(verbose_name=("Фрагмент Статьи"), max_length=200)
likes = models.ManyToManyField(User, related_name='blog_post')
updated_on = models.DateTimeField(auto_now= True)
def total_likes(self):
return self.likes.count()
def __str__(self):
return self.title + ' | ' + str(self.author)
def get_absolute_url(self):
return reverse('article_detail', args=[str(self.id)])
views.py/members
class CreateProfilePageView(CreateView):
model = Profile
form_class = ProfilePageForm
template_name = "registration/create_user_profile.html"
#fields = '__all__'
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
class EditProfilePageView(generic.UpdateView):
model = Profile
template_name = 'registration/edit_profile_page.html'
fields = ['bio', 'profile_pic', 'website_url', 'instagram_url', 'twitter_url', 'status', 'age']
success_url = reverse_lazy('home')
class ShowProfilePageView(DetailView):
model = Profile
template_name = 'registration/user_profile.html'
def get_context_data(self, *args, **kwargs):
#users = Profile.objects.all()
context = super(ShowProfilePageView, self).get_context_data(*args, **kwargs)
page_user = get_object_or_404(Profile, id=self.kwargs['pk'])
context["page_user"] = page_user
return context
class PasswordsChangeView(PasswordChangeView):
form_class = PasswordChangingForm
#form_class = PasswordChangeForm
success_url = reverse_lazy('password_success')
#success_url = reverse_lazy('home')
def password_success(request):
return render(request, 'registration/password_success.html', {})
class UserRegisterView(generic.CreateView):
form_class = SignUpForm
template_name = 'registration/registr.html'
success_url = reverse_lazy('login')
class UserEditView(generic.UpdateView):
form_class = EditProfileForm
template_name = 'registration/edit_profile.html'
success_url = reverse_lazy('home')
def get_object(self):
return self.request.user
views.py/blogapp
class HomeView(ListView):
model = Post
queryset = Post.objects.filter(draft=False)
cats = Category.objects.all()
template_name = 'home.html'
ordering = ['-post_date']
paginate_by = 6
def get_context_data(self, *args, **kwargs):
cat_menu = Category.objects.all()
context = super(HomeView, self).get_context_data(*args, **kwargs)
context["cat_menu"] = cat_menu
return context
def CategoryListView(request):
cat_menu = Category.objects.all()
return render(request, 'category_list.html', {'cat_menu':cat_menu})
def CategoryView(request, cats):
category_posts = Post.objects.filter(category = cats). order_by('-post_date')
return render(request, 'categories.html', {'cats':cats.title(), 'category_posts':category_posts})
class ArticleDetailView(HitCountDetailView):
model = Post
template_name = 'post_detail.html'
count_hit = True
def get_context_data(self, *args, **kwargs):
cat_menu = Category.objects.all()
context = super(ArticleDetailView, self).get_context_data(*args, **kwargs)
stuff = get_object_or_404(Post, id=self.kwargs['pk'])
total_likes = stuff.total_likes()
context["cat_menu"] = cat_menu
context["total_likes"] = total_likes
return context
class AddPostView(CreateView):
model = Post
form_class = PostForm
template_name= 'add_post.html'
#fields = '__all__'
class AddCommentView(CreateView):
model = Comment
form_class = CommentForm
template_name= 'add_comment.html'
def form_valid(self, form):
form.instance.post_id = self.kwargs['pk']
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy('article_detail', kwargs={'pk': self.kwargs['pk']})
class AddCategoryView(CreateView):
model = Category
template_name= 'add_category.html'
fields = '__all__'
class UpdatePostView(UpdateView):
model = Post
template_name = 'update_post.html'
form_class = EditForm
#fields = ['title', 'body']
class DeletePostView(DeleteView):
model = Post
template_name = 'delete_post.html'
success_url = reverse_lazy('home')
If you need any more code, I will attach it, thanks, and forgive my english)
Hello asd you can add flags like this in your Profile Model like this
class Profile(models.Model):
user = models.ForeignKey(User,on_delete=models.PROTECT)
is_moderator = models.BooleanField(default=False)
is_editor = models.BooleanField(default=False)#you can add many more as you want
and you can validate user in template or in views like this
in views.py
def check_user(request):
moderator_profile = Profile(user_id=request.user.id,is_moderator=True)
editor_profile = Profile(user_id=request.user.id,is_editor=True)
if user_profile:
return redirect('url_for_moderator')
elif editor_profile:
return redirect('url_for_editor')
OR
you can pass data to the template and give certain functionality for certain user
like this
in your views.py
def get_post(request):
user_profile = Profile.objects.filter(user=request.user.id)
return render(request,"post.html",{"user_profile":user_profile})
and inside post.html
{% if user_profile.is_editor or user_profile.is_moderator %}
<button>Edit</button>
{% endif %}
if you don't like this way you can do it in better way check this post
https://simpleisbetterthancomplex.com/tutorial/2018/01/18/how-to-implement-multiple-user-types-with-django.html

Get post id in a Class based view

Trying to get post id in Detailview in views.py .I am trying to add like button on blog Detail page.
I think I need to add id in kwargs in get_absolute_url function but that didn't work or I didn't add that correctly.so, please help me.
#views.py
class PostDetail(DetailView):
model = Post
template_name = 'post_detail.html'
def get_context_data(self, *args, **kwargs):
context = super(PostDetail, self).get_context_data(*args, **kwargs)
post = get_object_or_404(Post, id=self.kwargs['id'])
is_liked = False
if post.likes.filter(id=request.user.id).exists():
is_liked = True
context["post"] = post
context["is_liked"] = is_liked
return context
model.py
class Post(models.Model):
cover = models.URLField(blank=True)
tag = models.CharField(max_length=100, unique=True, default=0)
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(accountUser, on_delete=models.CASCADE)
updated_on = models.DateTimeField(auto_now=True)
content = models.TextField()
likes = models.ManyToManyField(accountUser, related_name='likes', blank=True)
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
class Meta:
ordering = ["-created_on"]
def __str__(self):
return self.title
def total_likes(self):
return self.likes.count()
def get_absolute_url(self):
return reverse("post_detail", kwargs={"slug": str(self.slug)})
Error in terminal
#error
post = get_object_or_404(Post, id=self.kwargs['id'])
KeyError: 'id'
self.kwargs is different in get_context_data kwargs, and kwargs depend of your url
replace:
post = get_object_or_404(Post, id=self.kwargs['id'])
by :
post = self.get_object()
you are in DetailView, so you have methods get_object, for getting yout post object with verify if object exsits

Redirected by django updateview but not updated

I created an update screen for django. However, although it redirects to successURL, the data has not been updated. I don't know why.
I need your help.
I will post it if necessary.
#view
class RecordDetailEdit(UpdateView,LoginRequiredMixin):
template_name = 'records/detail_edit.html'
model = URC
form_class = RecordDetailEditForm
pk_url_kwarg = 'id'
success_url = reverse_lazy('person:home')
def get_object(self):
return get_object_or_404(User, pk=self.request.user.user_id)
def get_form_kwargs(self):
kwargs = super(RecordDetailEdit, self).get_form_kwargs()
# get users, note: you can access request using: self.request
kwargs['user'] = self.request.user
return kwargs
#form
class RecordDetailEditForm(forms.ModelForm):
class Meta:
model = URC
fields = ('UPRC','URN','UET','URT')
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
super(RecordDetailEditForm, self).__init__(*args, **kwargs)
self.fields['URN'].queryset = UPRM.objects.filter(user=user)
#model
class URC(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
UPRC = models.CharField(max_length=300)
URN = models.ForeignKey(UPRM, on_delete=models.CASCADE)
UET = models.DurationField(editable=True)
URT = models.DateTimeField(default=timezone.now,editable=True)
group = models.ForeignKey(group, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.UPRC
#url
path('<id>/edit/', views.RecordDetailEdit.as_view(), name='record_detail_edit'),
I changed it to the following.
def get_object(self, queryset=None):
obj = URC.objects.get(id=self.kwargs['id'])
return obj

django class view Overlapping

I am not good at English.
Please understand me.
I'm creating a blog in Django.
I am making it into class view, but I want to see a reple list and form in the post details view.
like this
enter image description here
POST detailview has already been implemented and I don't know how to add comments.
Should I be function view?
Give me some advice.
code
views.py
class BlogLV(LoginRequiredMixin,ListView):
model = Blog
def get_queryset(self):
return Blog.objects.exclude(user=self.request.user)
class BlogCV(LoginRequiredMixin,CreateView): # blog_form.html
model = Blog
fields = ['name','description','image']
success_url = reverse_lazy('blog:index')
def form_valid(self, form): #오류
form.instance.user = self.request.user #user 설정
form.instance.slug = self.request.user
return super(BlogCV,self).form_valid(form)
class BlogDV(LoginRequiredMixin,DetailView):
model = Blog
class PostCreateView(LoginRequiredMixin,CreateView):
model = Post
fields = ['title', 'content']
success_url = reverse_lazy('blog:index')
template_name = 'blog/post_form.html'
def get_context_data(self, **kwargs):
context = super(PostCreateView, self).get_context_data(**kwargs)
context['blog'] = Blog.objects.get(slug=self.kwargs['slug'])
return context
def form_valid(self, form):
form.instance.user = self.request.user
form.instance.slug = self.request.user
return super(PostCreateView, self).form_valid(form)
class PostDV(LoginRequiredMixin,DetailView):
model = Post
fields =['title','content']
def get_context_data(self, **kwargs):
context = super(PostDV, self).get_context_data(**kwargs)
context['blog'] = Blog.objects.get(slug=self.kwargs['slug'])
return context
class PostLV(LoginRequiredMixin,ListView):
model = Post
paginate_by = 5
def get_context_data(self, *, object_list=None, **kwargs):
context = super(PostLV,self).get_context_data(**kwargs)
context['blog'] = Blog.objects.get(slug=self.kwargs['slug'])
return context
def get_queryset(self):
return Post.objects.filter(slug=self.kwargs['slug'])
class PostDeleteView(LoginRequiredMixin,DeleteView):
model = Post
success_url = reverse_lazy('blog:index')
def get_context_data(self, *, object_list=None, **kwargs):
context = super(PostDeleteView,self).get_context_data(**kwargs)
context['blog'] = Blog.objects.get(slug=self.kwargs['slug'])
return context
class PostUV(LoginRequiredMixin,UpdateView):
model = Post
fields = ['title','content']
success_url = reverse_lazy('blog:index')
def get_context_data(self, *, object_list=None, **kwargs):
context = super(PostUV,self).get_context_data(**kwargs)
context['blog'] = Blog.objects.get(slug=self.kwargs['slug'])
return context
urls.py
urlpatterns = [
url(r'^$',BlogLV.as_view(),name="index"),
url(r'^create/$',BlogCV.as_view(),name='blog_create'),
url(r'^(?P<slug>[-\w]+)/$',BlogDV.as_view(),name='blog_detail'),
url(r'^(?P<slug>[-\w]+)/post/create/$',PostCreateView.as_view(),name='post_create'),
url(r'^(?P<slug>[-\w]+)/post/$',PostLV.as_view(),name='post_list'),
url(r'^(?P<slug>[-\w]+)/post/(?P<pk>[0-9]+)/$', PostDV.as_view(), name='post_detail'),
url(r'^(?P<slug>[-\w]+)/update/(?P<pk>[0-9]+)/$', PostUV.as_view(), name='post_update'),
url(r'^(?P<slug>[-\w]+)/delete/(?P<pk>[0-9]+)/$', PostDeleteView.as_view(), name='post_delete'),
]
models.py
#python_2_unicode_compatible
class Blog(models.Model): # 유저 당 하나
name = models.CharField(max_length=20)
description = models.CharField(max_length=30)
image = models.ImageField(upload_to='blog/profile')
create_date = models.DateTimeField(auto_now_add=True)
slug = models.SlugField(unique=True,allow_unicode=True)
# 블로그 생성한 시각
# 저장 경로: MEDIA_ROOT/blog/projile/xxx.jpg 파일 저장
# DB 필드 'MEDIA_URL/blog/profile/xxx.jpg' 문자열 저장
user = models.OneToOneField(User)
class Meta:
ordering = ['-create_date']
# 생성된 날짜의 내림차순으로 정렬
def __str__(self):
return self.name
#python_2_unicode_compatible
class Post(models.Model):
title = models.CharField(max_length=30)
content = models.TextField()
create_date = models.DateTimeField(auto_now_add=True)
modify_date = models.DateTimeField(auto_now=True)
user = models.ForeignKey(User)
slug = models.SlugField(allow_unicode=True,default='slug')
class Meta :
ordering = ['-create_date']
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:post_detail',args=(self.id,))
# post.get_absolute_url args
# 객체가 지칭하는 url 반환
def get_previous_post(self):
return self.get_previous_by_create_date()
#create_date 기준으로 이전 포스트 반환
# get_previous_by_column 내장객체 호출
def get_next_post(self):
return self.get_next_by_create_date()
#python_2_unicode_compatible
class Reple(models.Model):
content = models.TextField()
user = models.ForeignKey(User)
Post = models.IntegerField() # post_id
create_date = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-create_date']
def __str__(self):
return self.content
It's my first time writing, so I don't know how to Indent. Sorry
And if my code is not effective, tell me how to fix it.
thank you!
It might be easier to write the view from scratch as a function, but you can also override the existing post method to return additional data.