Database Error - no such column - django

I have a project, with an app, article. And there I have a page to list all the articles, and another to display the selected article and its comments. Everything was fine before I used migration from south, and made some changes, i.e., before in the Comment model i had a field for
name = models.CharField(max_length=200)
and changed it to:
first_name = models.CharField(max_length=200)
second_name = models.CharField(max_length=200)
Now when i load my articles.html page, everthings ok, but when i load article.html, i get an error:
DatabaseError at /articles/get/1/
no such column: article_comment.first_name
Error during template rendering
In template C:\Users\Robin\web\django_test\article\templates\article.html, error at line 21
In in line 21 article.html:
{% if article.comment_set.all %}
I think the problem is with comment_set.all. Even in the console it gives me the same error as the above. So, how do i get all the comments from the given aritcle? Or did I made some mistake in the code? Any help will be greatly appreciated. Thank you.
Models.py:
from django.db import models
from time import time
def get_upload_file_name(instance, filename):
return "uploaded_files/%s_%s" % (str(time()).replace('.','_'), filename)
class Article(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
pub_date = models.DateTimeField('date published')
likes = models.IntegerField(default=0)
thumbnail = models.FileField(upload_to=get_upload_file_name)
def __unicode__(self):
return self.title
class Comment(models.Model):
first_name = models.CharField(max_length=200)
second_name = models.CharField(max_length=200)
body = models.TextField()
pub_date = models.DateTimeField('date published')
article = models.ForeignKey(Article)
views.py:
def article(request, article_id=1):
return render_to_response('article.html',
{'article': Article.objects.get(id=article_id) })
forms.py:
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('first_name','second_name', 'body')
article.html:
{% extends "base.html" %}
{% block sidebar %}
<ul>
<li>Articles</li>
</ul>
{% endblock %}
{% block content%}
<h1>{{article.title}}</h1>
<p>{{article.body}}</p>
{% if article.thumbnail %}
<p><img src="/static/assets/{{ article.thumbnail }}" width="200"/></p>
{% endif %}
<p>{{ article.likes }} people liked this article.</p>
<p>Like</p>
<h2>Comments</h2>
{% if article.comment_set.all %}
{% for c in article.comment_set.all %}
<p>{{ c.name }}: {{ c.body }}</p>
{% endfor %}
{% else %}
<p>No comment</p>
{% endif %}
<p>Add comment</p>
{% endblock %}

Related

Django displaying related objects

I have models for ProjectNotes and for ProjectNotesComments. ProjectNotesComments have a foreign key that is the ProjectNotes id. I am able to save comments on notes. I can see them in the admin panel.
However I have not been able to figure out how to display the comments on the notes.
Here are the models:
class ProjectNotes(models.Model):
title = models.CharField(max_length=200)
body = tinymce_models.HTMLField()
date = models.DateField(auto_now_add=True)
project = models.ForeignKey(Project, default=0, blank=True, on_delete=models.CASCADE, related_name='notes')
def __str__(self):
return self.title
class ProjectNoteComments(models.Model):
body = tinymce_models.HTMLField()
date = models.DateField(auto_now_add=True)
projectnote = models.ForeignKey(ProjectNotes, default=0, blank=True, on_delete=models.CASCADE, related_name='comments')
Here is the view:
class ProjectNotesDetailView(DetailView):
model = ProjectNotes
id = ProjectNotes.objects.only('id')
template_name = 'company_accounts/project_note_detail.html'
comments = ProjectNotes.comments
This is the template I am currently using to test getting the comments to display:
{% extends 'base.html' %}
{% block content %}
<div class="section-container container">
<div class="project-entry">
<h2>{{ projectnotes.title }}</h2>
<p>{{ projectnotes.body | safe }}</p>
</div>
<div>
</div>
{% for comment in comments %}
<div class="comments" style="padding: 10px;">
<p class="font-weight-bold">
{{ comment.body | linebreaks }}
</div>
{% endfor %}
<h2>add note</h2>
{% endblock content %}
I don't think this actually works: comments = ProjectNotes.comments. You would need to override the get_context_data method, and set comments on the context_data to accomplish what you are attempting to do there.
However, you don't need to do that at all, since you can get to the comments from the ProjectNotes object, and the ProjectNotes object is already in the context. Simply change your for loop to this:
{% for comment in projectnotes.comments %}

How to delete a record only if the user posted is the logged in user

I have multiple users in my project
my models.py file is
class User(AbstractUser):
is_student = models.BooleanField(default=False)
is_teacher = models.BooleanField(default=False)
class Teacher(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE,primary_key=True,related_name='Teacher')
name = models.CharField(max_length=250)
subject_name = models.CharField(max_length=250)
email = models.EmailField(max_length=254)
phone = models.IntegerField()
teacher_profile_pic = models.ImageField(upload_to="classroom/teacher_profile_pic",blank=True)
def __str__(self):
return self.name
class Announcement(models.Model):
title = models.CharField(max_length=30)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
def __str__(self):
return self.title
If the logged in user is a teacher it is allowed to create an announcement
Now i want that only the teacher who posted the announcement should be able to see the delete button
My html file is
{% extends "classroom/base.html" %}
{% block content %}
<h1>Announcements</h1>
{% for announcement in announcements %}
<!-- starting loop (posts is keyword from view) -->
<div style="border-style: solid;">
{% if object.teacher.id == request.teacher %}
<div>
Delete
</div>
{% endif %}
<a class="mr-2">Posted by: {{ announcement.teacher }}</a>
<h2><a class="article-title">{{ announcement.title }}</a></h2>
<p class="article-content">{{ announcement.content}}</p>
</div>
{% endfor %}
{% endblock content %}
the if statement is supposed to be true if logged in teacher is the teacher who originally posted it. However the delete button is visible for every announcement
my views.py has
class AnnouncementListView(ListView):
context = {
'announcements' : Announcement.objects.all()
}
model = Announcement
template_name = 'classroom/all_announcements.html'
context_object_name = 'announcements'
Try using this.
{% if announcement.teacher.user == request.user %}
<div>
Delete
</div>
{% endif %}
Your models are a bit "unconventional".
However, this should work:
{% if announcement.teacher.user == request.user %}
...
{% endif %}

Django _set.all in template with one to many relationship

I am trying to output a web page with many blog posts, each of them potentially containing many images.
Models.py:
class FreeImage(models.Model):
f_img = models.ImageField(null=True, blank=True, upload_to="img/f")
f_img_alt = models.CharField(max_length=100, blank=True, null=True)
post = models.ForeignKey('Post', on_delete=models.SET_NULL, null=True)
class Post(models.Model):
title = models.CharField(max_length=100, unique=True)
Views.py:
def home_view(request):
posts = Post.objects.order_by('-id')
freeimgs = FreeImage.objects.filter(post__in=posts)
context = {
'posts':posts,
'freeimgs' :freeimgs,}
return render(request, 'home.html', context)
Template:
{% extends 'base.html' %}
{% block main %}
{% for post in posts%}
<h3>{{post.title}}</h3>
{% for i in freeimgs.post_set.all %}
<h5>Test</h5>
<img src="{{ freeimage.f_img.url }}" alt="{{freeimage.f_img_alt}}">
{% endfor %}
{% endfor %}
{% endblock %}
freeimgs.post_set.all does not return anything here. I have no idea how else I could show the images corresponding to the right post inside template.
You have reverse accessor from Post to FreeImage and not other way around
{% for free_image in post.freeimage_set.all %}
<h5>Test</h5>
<img src="{{ free_image.f_img.url }}" alt="{{ free_image.f_img_alt}}">
{% endfor %}

Get Featured Image from different Model

I have 2 model objects, Business & BusinessImage as so, listed with views and index.html. I am trying to list the business's featured image, but it's not happening. I am getting the following error:
'QuerySet' object has no attribute 'businessimage_set'
How can I get the business featured image for a list?
Business
class Business(models.Model):
name = models.CharField("Name", max_length=70, default="Business Name")
slug = models.SlugField()
description = models.TextField("About", max_length=400)
category = models.ManyToManyField(Category, verbose_name="Categories", blank=True)
order = models.IntegerField("Order", default=0)
claimed = models.BooleanField("Claimed", default=False)
featured = models.BooleanField("Featured", default=False)
class Meta:
ordering = ['order']
verbose_name = "Business"
verbose_name_plural = "Businesses"
def __str__(self):
return self.name
BusinessImage
class BusinessImage(models.Model):
business = models.ForeignKey(Business)
image = models.ImageField(upload_to="images/business")
title = models.CharField(max_length=120)
featured = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return self.title
view.py
from .models import Business, BusinessImage
def index_view(request):
latest_business_list = Business.objects.all()
images = latest_business_list.businessimage_set.all()
template = loader.get_template('index.html')
context = RequestContext(request, {
'latest_business_list': latest_business_list,
'images': images,
})
return HttpResponse(template.render(context))
index.html
{% block content %}
<div class="text-center business_title">
<h2>Featured</h2>
</div>
{% if latest_business_list %}
{% for business in latest_business_list|slice:":4" %}
{% if business.active %}
<div class="col-sm-6 col-md-3">
<li>{{ business.name }}</li>
{% for image in latest_business_list.businessimage_set.all %}
{% if image.featured %}
<a href="{% url 'single_product' product.slug %}">
<img src="{{MEDIA_URL}}{{image.image}}" alt="{{image}}">
</a>
{% endif %}
{% endfor %}
</div>
{% endif %}
{% endfor %}
{% endif %}
{% endblock %}
businessimage_set is an attribute of a Business instance, but you're trying to access it as an attribute of a queryset (i.e. list of businesses). If your goal is just to be able to access the images for each business in a template, you can leave out images entirely. Instead your template would have:
{% for image in business.businessimage_set.all %}
(Though look into prefetch_related for efficiency.)

Django model relationships in views and templates

I'm working on multi-user rss reader. I want to limit display of posts only to those which are unread. I've managed to do this in my single "feed" view as below, but I can't figure out how to do the same in multiple feed aka "category" view.
I've been trying something like here https://docs.djangoproject.com/en/1.5/topics/db/queries/#spanning-multi-valued-relationships but it didn't work for me
Should I change my "category" view code or template code? and if so how would you go about it?
thanks!
-S
models
class UserCategory(models.Model):
name = models.CharField(unique=False, max_length=64)
user = models.ForeignKey(User)
slug = AutoSlugField(populate_from='name', always_update='True', unique_with='user')
class Feed(models.Model):
feed_url = models.URLField(unique=True)
default_title = models.CharField(max_length=64, blank=True)
link = models.URLField(blank=True)
class UserFeed(models.Model):
feed = models.ForeignKey(Feed)
title = models.CharField(max_length=64)
category = models.ForeignKey(UserCategory)
user = models.ForeignKey(User)
slug = AutoSlugField(populate_from='title', always_update='True', unique_with='user')
class Post(models.Model):
feed = models.ForeignKey(Feed)
title = models.CharField(max_length=256)
content = models.TextField()
link = models.URLField(max_length=512)
class ReadPost(models.Model):
user = models.ForeignKey(User)
post = models.ForeignKey(Post)
views
def feed(request, user_feed_slug):
user_feed = get_object_or_404(UserFeed.objects.filter(slug=user_feed_slug, user=request.user))
read_post = ReadPost.objects.filter(user=request.user).values_list('post')
posts = Post.objects.select_related().filter(feed=user_feed.feed).exclude(id__in=read_post)
def category(request, user_category_slug):
user_category = get_object_or_404(UserCategory.objects.filter(slug=user_category_slug, user=request.user))
templates
feed
{% for post in posts %}
{{ post.title }}
{% endfor %}
category
{% for feed in user_category.userfeed_set.all %}
{{ feed.title }}
{% for post in feed.feed.post_set.all %}
{{ post.title }}
{{ post.content }}
{% endfor %}
{% endfor %}
You can write custom template filter, i.e:
#register.filter
def unread(posts, read_posts):
return posts.exclude(id__in=read_posts)
(before you must pass read_post to category template context).
Try this queryset:
def category(request, user_category_slug):
user_category = get_object_or_404(UserCategory, slug=user_category_slug,
user=request.user))
feeds = UserFeed.objects.filter(category__slug=user_category_slug, user=request.user)\
.prefetch_related('feed__post_set')
then in your template:
{% for feed in feeds %}
{{ feed.title }}
{% for post in feed.feed.post_set.all %}
{{ post.title }}
{{ post.content }}
{% endfor %}
{% endfor %}