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
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.
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
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
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 }}.
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.