i am creating a simple blog website in django and have a model which contains time at which the blog will be published when in views i am trying to sort the post according to time it is giving error 'function' object has no attribute 'order_by'
my views.py:
class AboutView(TemplateView):
template_name = 'blog/about.html'
class Postlistview(ListView):
model = Post
def get_queryset(self):
return Post.objects.filter(published_date__lte=timezone.now.order_by('-published_date'))
my models.py :
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=100)
text = models.TextField(max_length=200)
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = models.DateTimeField(default=timezone.now)
self.save()
def get_absolute_url(self):
return reverse('post_detail', kwargs={'pk': self.pk})
def approve_comments(self):
return self.comments.filter(approved_comments=True)
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey('blog.Post', related_name='comments', on_delete=models.CASCADE)
text = models.CharField(max_length=200)
author = models.CharField(max_length=20)
create_date = models.DurationField(default=timezone.now)
approved_comments = models.BooleanField(default=False)
def approve(self):
self.approved_comments = True
self.save()
def get_absolute_url(self):
return reverse('post_list')
def __str__(self):
return self.text
i think it is rather like this:
return Post.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')
the order_by must be outside of your filter.
Related
When i'm trying to add a Post through django admin i get an error that the Post im trying to add needs to have a value for field id. Do you have any idea why?
now = datetime.now()
class Category(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
class Meta:
verbose_name_plural = "categories"
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=100)
excerpt = models.CharField(max_length=200)
main_image = models.ImageField()
author = models.ForeignKey(users.models.CustomUser, on_delete=models.CASCADE, related_name='blog_posts', null=True)
content = models.TextField(null=True)
created_at = models.DateTimeField(editable=False)
updated_at = models.DateTimeField(editable=False)
category = models.ManyToManyField(Category, related_name='post_category')
class Meta:
ordering = ['-created_at']
def save(self, *args, **kwargs):
if not self.id:
self.created_at = now
self.updated_at = now
def __str__(self):
return self.title
You need to make a super().save(*args, **kwargs) call. Furthermore using a constant will not work: this will assign the time when you started the server, not the current time, so:
from django.utils.timezone import now
class Post(models.Model):
# …
def save(self, *args, **kwargs):
if not self.id:
self.created_at = now()
self.updated_at = now()
super().save(*args, **kwargs)
You furthermore do not need to specify logic to update the created_at and updated_at field, you can work with auto_now_add=True [Django-doc] and auto_now=True [Django-doc]:
class Post(models.Model):
# …
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
# …
class Meta:
ordering = ['-created_at']
# no save override
def __str__(self):
return self.title
I am learning django. I am very new to programming. I have one model as below:
class Group(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=200)
group_description = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
def get_absolute_url(self):
self.save()
return reverse('group-detail', kwargs={'pk': self.pk})
now I am creating another model which needs the pk value of the above Group model:
class GroupPost(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('group-post-detail', kwargs={'pk': Group.pk, 'pk2': self.pk})
when I give just Group.pk it is erroring out giving the below information.
Reverse for 'group-post-detail' with keyword arguments '{'pk': , 'pk2': 73}' not found. 1 pattern(s) tried: ['groups/(?P[0-9]+)/post/(?P[0-9]+)/$']
How can I get rid of the error message. what is the correct way to proceed? Any help would be appreciated.
Thank you
You should have a many-to-one relationship (ForeignKey) with the Group model from the GroupPost model, as each post belongs to a certain group and one group can have many posts.
So add a ForeignKey:
class GroupPost(models.Model):
...
group = models.ForeignKey('Group', on_delete=models.CASCADE)
Now, you can refer the related Group id (or pk) from a GroupPost instance:
def get_absolute_url(self):
return reverse('group-post-detail', kwargs={'pk': self.group.pk, 'pk2': self.pk})
# ^^^^^^ Here
Assuming the view name is group-post-detail.
Also, rather than referring URL keywords as pk and pk2, you can be more explicit:
def get_absolute_url(self):
return reverse('group-post-detail', kwargs={'group_pk': self.group.pk, 'group_post_pk': self.pk})
I am very new to django and programming. I am seeing the below error when trying to run
No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model.
below is my model definition
class Group(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=200)
group_description = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
def get_absolute_url(self):
self.save()
return reverse('group-detail', kwargs={'pk': self.pk})
class GroupPost1(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
group1 = models.ForeignKey('Group', on_delete=models.CASCADE, null=True)
def __str__(self):
return self.title
def get_absolute_url(self):
self.save()
return reverse('group-post-detail', kwargs={'group_pk': self.group1.id, 'group_post_pk': self.pk})
I have get_absolute_url def in my model. Why am I seeing this error?. any help would be appreciated
Thank you
im not sure if this helpes, but i don't think its necessary to type self.save() when you define the get_absolute_url method. If you use built-in class based views for example django.views.generic.CreateView this will automatically take care of the saving.
I am having trouble trying to implement a delete function-based view as I am unsure of what is the correct syntax.
So far this is the method that I am using:
def delete_lesson(request, post_id):
if request.method == 'POST':
lesson = Lesson.objects.get(post_id=request.get('post_id'))
lesson.delete()
return redirect('/')
I have implemented the delete function in my model:
class Lesson(models.Model):
title = models.CharField(max_length=100)
file = models.FileField(upload_to="lesson/pdf")
date_posted = models.DateTimeField(default=timezone.now)
post = models.ForeignKey(Post, on_delete=models.CASCADE, null=False, blank=False)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('lesson_upload', kwargs={'pk': self.pk})
def delete(self, *args, **kwargs):
self.file.delete()
self.title.delete()
super().delete(*args, **kwargs)
class Post(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(default = 'default0.jpg', upload_to='course_image/')
description = models.TextField()
price = models.DecimalField(decimal_places=2, max_digits=6)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
rating = models.IntegerField(default = 0)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk' : self.pk})
My urls.py:
path('post/<int:post_id>/lesson_delete/', views.delete_lesson, name='delete_lesson'),
You have a post_id in your URL which passes the id to your view which you also received.
So if you want to remove the post with the id in your URL then this is how you can do:
lesson = Lesson.objects.get(post_id=post_id)
If for any reasons you get a post id from your template and it's different than the post id in your URL, then this is how you should do it:
Lesson.objects.get(post_id=request.POST.get('post_id'))
Note if you're using the second option which the post_id you want to delete is different than what you have in post/<int:post_id>/lesson_delete/ then you should pass the post_id as a POST data from your template.
I have created 'post' model in which I included 'post_id' as the primary key field. When I am trying to create a post, it is raising an error: 'badly formed hexadecimal UUID string'. I would appreciate helping me in solve this.
Here's my code.
Models.py:
class Post(models.Model):
post_id = models.UUIDField(primary_key=True, default='uuid.uuid4', editable=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
from1 = models.CharField(max_length=20)
To = models.CharField(max_length=20)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
objects = PostManager()
def __unicode__(self):
return self.post_id
def __str__(self):
return self.post_id
def get_absolute_url(self):
return reverse("posts:detail", kwargs={"post_id": self.post_id})
class Meta:
ordering = ["-timestamp", "-Time"]
views.py:
def post_create(request):
form = PostForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
print(form.cleaned_data.get("post_id"))
instance.user = request.user
instance.save()
return HttpResponseRedirect(instance.get_absolute_url())
context = {
"form": form,
}
return render(request, "loggedin_load/post_load.html", context)
I would do something like this:
from django.utils.encoding import python_2_unicode_compatible
#python_2_unicode_compatible
class Post(models.Model):
# Instead of default, maybe do null=True to take old entries into account?
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
from1 = models.CharField(max_length=20)
# You may want to reconsider the naming of the "To" field
# to avoid capital letters and built-in functions
To = models.CharField(max_length=20)
timestamp = models.DateTimeField(auto_now_add=True)
objects = PostManager()
# You can remove this with the decorator above
# def __unicode__(self):
# return self.id
def __str__(self):
return self.id # acts as your post_id
def get_absolute_url(self):
return reverse("posts:detail", kwargs={"post_id": self.id})
class Meta:
ordering = ["-timestamp", "-Time"]
Whenever an object is created, it will automatically be assigned an id, which will populate your __unicode__, __str__, and get_absolute_url.
You need to import the module and not use quotes around 'uuid.uuid4'.
It should be somewhat like:
import uuid # The uuid module
class Post(models.Model):
post_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) # using the function uuid4 on the module
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
from1 = models.CharField(max_length=20)
To = models.CharField(max_length=20)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
objects = PostManager()
def __unicode__(self):
return self.post_id
def __str__(self):
return self.post_id
def get_absolute_url(self):
return reverse("posts:detail", kwargs={"post_id": self.post_id})
class Meta:
ordering = ["-timestamp", "-Time"]
N.B I've not tested the above code, and I agree with some of the comments you shouldn't need a UUID for the post_id. Without knowing more I couldn't help further.