Django blog post by authors - python

I am building a blog in django 3. I want to filter all posts by author and display the results in author page. I can't seem to figure what is wrong with my code. Please help. If i can get an explaination on what is wrong with my code, that will be appreciated.
Views.py
class AuthorPostListView(ListView):
model = Post
paginate_by = 5
template_name = 'author_post.html'
def get_queryset(self):
return Post.objects.filter(author = self.request.user).order_by('created_on').reverse()
def get_context_data(self):
context = super(AuthorPostListView, self).get_context_data(**kwargs)
context['authorpost_list'] = Post.objects.all()
return context
Models.py
class Post(models.Model):
title = models.CharField(max_length=200)
post_slug = models.SlugField(max_length = 200, unique = True)
body = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now = True)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name = 'blog_posts',
)
post_picture = models.ImageField(
upload_to = 'post_picture',
null = True,
blank = True,
default='/media/post_picture/2.jpg',
)
approved_comment = models.BooleanField(default=True)
tags = TaggableManager()
categories = models.ManyToManyField('Category', related_name = 'posts')
def approve(self):
self.approved_comment = True
self.save()
class Meta:
ordering = ['created_on']
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post_detail', args=[str(self.id)])
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
Template
{% for object in authorpost_list %}
{{ object.title }}
{% endfor %}
urls.py
urlpatterns = [
path('author_post/', views.AuthorPostListView.as_view(), name = 'author_posts'),
]

you are over-riding the actual view you wanted with get context data, so you can remove the get context method and call in the template as
{% for object in object_list %}
{{ object.title }}
{% endfor %}
or you can do
context['authorpost_list'] = Post.objects.filter(author = self.request.user).order_by('-created_on')
and call in template in the same way as you shown

Related

How to return a value from another model using the Django Rest Framework?

When I query all the comments of the post, I want to return the user's username.
My two Models:
class Comment(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
post = models.ForeignKey(
Post, on_delete=models.CASCADE, null=False, blank=False)
title = models.TextField()
date = models.DateField(auto_now=True)
class User(AbstractUser):
objects = UserManager()
username = models.CharField(max_length=60, unique=True)
avi_pic = models.ImageField(
_('avi_pic'), upload_to=aviFile, null=True, blank=True)
My Comments Serializer:
class CommentSerializer(serializers.ModelSerializer):
username = serializers.SerializerMethodField('get_username_from_user')
avi_pic = serializers.SerializerMethodField('get_avi_pic')
class Meta:
model = Comment
fields = '__all__'
def get_username_from_user(self, comment):
username = comment.user.username
return username
def get_avi_pic(self, comment):
request = self.context['request']
avi_pic = comment.user.avi_pic.url
return request.build_absolute_uri(avi_pic)
My Comments View:
class CommentView(APIView):
authentication_class = [authentication.TokenAuthentication]
permission_class = [permissions.IsAuthenticated]
serializer_class = CommentSerializer
# Get all comments from current post
def get(self, request):
post_id = request.data.get('id')
post = Post.objects.get(id=post_id)
comment = Comment.objects.filter(post=post).values()
serializer = CommentSerializer(comment)
return Response(serializer.data, status=status.HTTP_200_OK)
In my console I get: 'QuerySet' object has no attribute 'user'
Appreciate any help!!
In views.py:
comment = Comment.objects.filter(post=post)
In serializer.py:
def get_username_from_user(self, comment):
username = comment.user.username
return username
In views.py:
def get(self, request):
...
serializer = CommentSerializer(comment, many=True)
...
In my humble opinion, your problem is not having a ForeignKey for the "User" model, meaning whatever model you are trying to render doesn't have a column named 'user'. I'd do something like this:
models.py
class User(AbstractUser):
pass
def __str__(self):
return f"{self.username}"
class Comment(models.Model):
comment = models.TextField(max_length=300, null=True)
creation_date = models.DateTimeField(default=timezone.now)
user = models.ForeignKey(User, on_delete=models.CASCADE)
whatever_name = models.ForeignKey(whatever_model_to_relate, on_delete=models.CASCADE, related_name="comments")
forms.py
class CommentForm(ModelForm):
class Meta:
model = Comment
fields = ['comment']
widgets = {
'comment': forms.Textarea(attrs={'rows':4, 'cols':100}),
}
views.py
#login_required
def whatever_function(request, id):
whatever_name = whatever_related_model.objects.get(id=id)
return render(request, "template.html", {
"whatever_name_for_template": whatever_name,
"commentform": CommentForm()
})
template.html
{% for comment in whatever_related_model.comments.all %}
<div class="card p-1 m-2 col-lg-12 col-sm-12">
<div class="card-body">
<h5 class="card-title">{{ comment.user }}</h5>
<h6 class="card-subtitle mb-2 text-muted">{{ comment.creation_date }}</h6>
{{ comment.comment }}
</div>
</div>
{% endfor %}
Hopefully I didn't get sidetracked from your question.

How to pass unique objects from a second model in ListView function to the template django

I am creating a blog app in django. For that, I have made a page where all available blogs are listed. I am using generic.ListView view to achieve this. But, I also want to create a writer's section where I can list some details about the writers that have written those blogs. For this, I need to get all the users that have written a blog and then find distinct users from that and list out their username. I have an author field in my Blog model that keeps track of the writer user. How can I get the distinct usernames of these writers and pass it into my template?
Models.py:
class Blog(models.Model):
blog_head = models.CharField(max_length=100)
blog_header_image = models.ImageField(upload_to="photos/blogs/", null=True, blank=True)
#blog_content = models.TextField()
blog_content = RichTextField(blank=True, null=True)
#blog_summary = models.TextField(max_length=355)
blog_summary = models.CharField(max_length=100)
author = models.ForeignKey(User, on_delete=models.CASCADE)
blog_date = models.DateField(auto_now_add=True)
likes = models.ManyToManyField(User, related_name='blog_post_likes', blank=True)
def __str__(self):
return self.blog_head
def get_absolute_url(self):
return reverse('blog-full', args=[str(self.id)])
def blog_likes_count(self):
return self.likes.count()
Views.py:
class blogs_getting_Listview(ListView):
model = Blog
template_name = 'blogs.html'
ordering = ["-blog_date"]
def get_context_data(self, *args, **kwargs):
context = super(blogs_getting_Listview, self).get_context_data()
authors_id_list = Blog.objects.get(id=id).author
authors_list = ""
for author_in in authors_id_list:
author_obj = User.objects.get(id=author_id)
authors_list = authors_list + author_obj
context.update({
"authors_list": authors_list
#'more_context': Model.objects.all(),
})
print(type(context["authors_list"]))
return context
urls.py:
urlpatterns = [
#path('', views.blogs_getting, name='blogs/'),
path('', blogs_getting_Listview.as_view(), name='blogs/'),
path('blog/<int:pk>', blogs_getting_Detailview.as_view(), name='blog-full'),
path('new_blog/', add_blog_view.as_view(), name='add_blog'),
path('update_blog/<int:pk>', edit_blog_view.as_view(), name='update_blog' ),
path('delete_blog/<int:pk>', delete_blog_view.as_view(), name='delete_blog' ),
path('like/<int:pk>', like_view, name='like_blog' ),
]+static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
template:
{% for author in authors_list %}
<p>{{ author }}</p>
{% endfor %}
(Here I am trying to render the author objects' queryset on my page.)
Thankful for any help
Try accessing directly the author entitie:
class blogs_getting_Listview(ListView):
model = Blog
template_name = 'blogs.html'
ordering = ["-blog_date"]
def get_context_data(self, *args, **kwargs):
context = super(blogs_getting_Listview, self).get_context_data()
authors = Blog.objects.get(id=id)
authors_list = ""
for author in authors:
author_obj = User.objects.get(id=author.id)
authors_list.append(author_obj)
context["authors_list"] = authors_list
return context

Django: the detail page is not showing(template error)

am working on a Django project where showing the details of post and amount
here is my models.py of post
class Loader_post(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE ,related_name="Loader")
pick_up_station = models.CharField(max_length=150)
destination_station = models.CharField(max_length=150)
sender_name = models.CharField(max_length=150)
phone_number = PhoneNumberField(null=False, blank=False, unique=True)
receiver_name = models.CharField(max_length=150)
def __str__(self):
return self.user.username
def get_absolute_url(self):
return reverse("Loader:my_job", kwargs={"pk": self.pk})
this is my second models which I inherit Loader post
class price(models.Model):
my_post = models.ForeignKey(Loader_post, related_name='prices',on_delete=models.CASCADE,
null=True, default='')
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, null=True, default='')
driver_price = models.CharField(max_length=150, null=True)
driver_name = models.CharField(max_length=150, null=True)
approved_price = models.BooleanField(default=False)
status = models.BooleanField(default=False)
def get_absolute_url(self):
return reverse("Driver:Driverview")
def __str__(self):
return self.driver_price
this is the view.py of both list and details view
class offer_view(ListView, SelectRelatedMixin):
context_object_name = 'offern'
model = Loader_post
template_name = "offer.html"
def get_queryset(self):
qs = Loader_post.objects.filter(user=self.request.user)
return qs
class offer_view_detail(DetailView):
context_object_name = 'offernew'
model = Loader_post
template_name = "offer_detail.html"
here is my HTML page of list view ...when someone clicks on it it shows the detail of next post
offer.html
{% for my in offern %}
{{my.sender_name}} {% endfor %}
and when someone clicks on its route to the detail page .. but it shows template doesn't exist
this is my detail page ie. offer_details.hml
<p>{{offernew.sender_name}}</p>
<p>{{offernew.receiver_name}}</p>
{% for x in offernew.prices.all %}
<p>
<p>{{x.driver_name}}</p>
</p>
and this is urls.py
path('offerdetail/<int:pk>', views.offer_view_detail.as_view(),name="offerdetail"),
path('offer/', views.offer_view.as_view(), name="offer"),
Following on from comments,
In you ListView,
{{my.sender_name}}
here, the url specified is not defined in your urls.py, that's why it was showing no template doesn't exist, changing to this would solve this.
{{my.sender_name}}
Now, To show prices model in your DetailView, i would do something like this.
class offer_view_detail(DetailView):
context_object_name='offernew'
model = Loader_post
template_name = "offer_detail.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['price_model'] = self.object.prices.all()
return context
and In your Template
<p>{{offernew.sender_name}}</p>
<p>{{offernew.receiver_name}}</p>
{% for x in offernew.price_model %}
<p>{{x.driver_name}}</p>
{% endfor %}
Django Docs for DetailView

how to get all records of related models and display dynamic data in django

I'm new in django.I want to retrieve all the records from related models and display the dynamic data in templates. I tried by using raw sql also but i could not display dynamic data templates.
models.py:
class NewRegistration(models.Model):
houseowner_name_en = models.CharField(max_length=30)
ward_no = models.ForeignKey(system_settings.models.Wardno)
contactno = models.CharField(max_length=30)
construction_type = models.ForeignKey(system_settings.models.ConstructionType)
taxpayer_id = models.CharField(max_length=30, blank=True, null=True)
cen = models.IntegerField()
is_forwarded = models.BooleanField(default=False)
class Application(models.Model):
registration_date = models.CharField(max_length=15)
building_use = models.ForeignKey(to=system_settings.models.BuildingUse)
building_category = models.CharField(max_length=30)
building_structure_category = models.ForeignKey(to=system_settings.models.BuildingStructureCategory)
building_storey = models.IntegerField(blank=True, null=True, default=0)
reg = models.ForeignKey(NewRegistration)
class Landowner(models.Model):
landowner_type = models.CharField(max_length=30)
lo_salutation = models.CharField(max_length=30)
lo_name_np = models.CharField(max_length=30)
lo_citizenship_issue_date = models.CharField(max_length=30)
reg = models.ForeignKey(NewRegistration)
views.py:
def export(request):
all_objects = NewRegistrationModel.objects.all()
# houseowner= all_objects.houseownerinfo_set.all()
app_all=Application.objects.all()
landinfo=Landinfo.objects.all()
return render(request, 'exports.html', {'all_objects': all_objects})
I did it like this.
views.py
def export(request):
all_objects = NewRegistration.objects.all()
return render(request, 'exports.html', {'all_objects': all_objects})
exports.html
# in template when displaying
{% for registration in all_objects %}
{{ registration.fiscalyear }}
{% for owner in registration.landowner_set.all %}
{{owner.landowner_type}}
{{owner.lo_wardno}}
{% endfor %}
{% endfor %}
you can use generic.ListView in your views.py file like that:
class Export(generic.ListView):
model = NewRegistration
template_name = "your_template_name.html"
def get_queryset(self):
return NewRegistration.objects.all()
def get_context_data(self, **kwargs):
context = super(Export, self).get_context_data(**kwargs)
context['app_all'] = Application.objects.all()
context['landinfo'] = Landingo.objects.all()
return context
you can accees the datas in your template like that {{ app_all }} or {{ landinfo }}.

Django view with get context not working

Have a quick question. Trying to use a relational model in one DetailView. However, no matter what I try the data does not display. I've tried a few versions of template tags to no avail.
html
{% for parts in relatedparts %}{{ parts.name }}
</div>{% endfor %}
views.py
class ErrorCodeView(DetailView):
context_object_name = 'error_code_details'
model = models.ErrorCodes
template_name = 'error_code_details.html'
def get_context_data(self, **kwargs):
# xxx will be available in the template as the related objects
context = super(ErrorCodeView, self).get_context_data(**kwargs)
context['relatedparts'] = RelatedParts.objects.filter(name=self.get_object())
return context
models.py
class ErrorCodes(models.Model):
name = models.CharField(max_length=256)
description = models.CharField(max_length=400)
instructions = models.CharField(max_length=256)
PartsNeeded = models.CharField(max_length=120, default='')
usercomments = models.CharField(max_length=400, default='', blank=True)
relpic = models.ImageField(upload_to='media/',blank=True)
relpictwo = models.ImageField(upload_to='media/',blank=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("errorcodes:errorcodeview",kwargs={'name':self.name})
class RelatedParts(models.Model):
name = models.CharField(max_length=256)
related_error_code = models.ForeignKey(ErrorCodes, on_delete=models.PROTECT)
def __str__(self):
return self.name
You don't need to do this at all. You can follow the relationship in the template.
{% for part in object.relatedparts_set.all %}{{ part.name }}{% endfor %}
You don't need any code in the view to enable this.
could it be that "name=self.get_object()" should be "name=self.get_object().name" ?
You currently have:
context['relatedparts'] = RelatedParts.objects.filter(name=self.get_object())
but that is probably producing an empty queryset.

Categories

Resources