django template not show ForeignKey items - django

I'm new to django I'm having a problem with my foreignkey items not displaying hope you can help me... thank you.
here's my models.py
class Reporter(models.Model):
name = models.CharField(max_length=20)
address = models.CharField(max_length=30)
def __str__(self):
return self.name
class News(models.Model):
headline = models.CharField(max_length=50)
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
def __str__(self):
return self.headline
and my views.py
def index(request):
reportlist = Reporter.objects.all()
context = {
'reportlist': reportlist
}
return render(request, 'index.html', context)
and my template
{% block content %}
{% for r in reportlist %}
<p>{{r.name}}</p>
{% for items in r.item_set.all%}
<p>{{items.headline}}</p>
{%endfor%} <br/>
{%endfor%}
{% endblock %}

{% block content %}
{% for r in reportlist %}
<p>{{r.name}}</p>
{% for items in r.news_set.all%}
<p>{{items.headline}}</p>
{%endfor%} <br/>
{%endfor%}
{% endblock %}
your model name is News so you need model_name_set, i.e. news_set

Related

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 'CharField' object has no attribute split

i am creating an website where a user can search for recipes by their ingredients. I wish that when a user finally see recipe, ingredients there would be splited with ', ' in view. for now it is just space. I tried to do this in my model, but they i get error as in title
- 'CharField' object has no attribute split.
Models:
from django.db import models
class Ingredient(models.Model):
ingredient_name = models.CharField(max_length=250)
igredient_name1 = ingredient_name.split(', ')
def __str__(self):
return self.ingredient_name1
class Recipe(models.Model):
recipe_name = models.CharField(max_length=250)
preparation = models.CharField(max_length=1000)
ingredients = models.ManyToManyField(Ingredient)
def __str__(self):
return self.recipe_name
template:
<div>
<h1>Drink drank drunk</h1>
</div>
{% for drink in results %}
<div>
<p>{{ drink.recipe_name }}</p>
<p>Preparation: {{ drink.preparation }}</p>
<p>Ingredients:
{% for ingredient in drink.ingredients.all %}
{{ingredient.ingredient_name}}
{% endfor %}
</p>
</div>
{% endfor %}
view:
def drink_list(request):
template = "drinks/drink_list.html"
return render(request, template)
def search_results(besos):
query = besos.GET.get('q')
q = Q()
for queries in query.split(', '):
q |= (Q(ingredients__ingredient_name__icontains=queries))
results = Recipe.objects.filter(q)
template = "drinks/search_results.html"
context = {
'results' : results,
}
return render(besos, template, context)
After some mess understanding what is needed to accomplish it seems that the solution is just to add the desired comma into the template, modifying the forloop as follows:
{% for ingredient in drink.ingredients.all %}}
{{ingredient.ingredient_name}}{% if not forloop.last %},{% endif %}
{% endfor %}

Display foriegnkey fields in Django template for a CreateView

I am trying to display a checklist in the CreateView using the values in the ForeignKey fields for descriptions.
models.py
class Structure(models.Model):
name = models.CharField(max_length = 30)
description =models.CharField(max_length = 300, null=True, blank=True)
def __str__(self):
return self.name
class SelectedFramework(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
structure = models.ForegignKey(Structure)
selected = models.BooleanField(default = False)
views.py
class FrameworkCreateView(generic.CreateView):
model = SelectedFramework
fields =['structure', 'selected']
template_name = 'catalogue/structure.html'
def form_valid(self, form):
form.instance.user = self.request.user
return super(FrameworkCreateView, self).form_valid(form)
structure.html
{% extends 'catalogue\base.html' %}
{% block container %}
<h2>{% block title %}Structures{% endblock title %}</h2>
<form action="" method="post">
{% csrf_token %}
{% for field in form %}
<div class="col-sm-10">{{form.structure}} {{form.selected}}</div><br>
{% endfor %}
</div>
</form>
{% endblock %}
The code above works but will display the ForeignKey 'structure' as a dropdown list with the values of __str__. Is there a way to display string for structure.name and structure.description with the checkbox from selected in the CreateView?
In your template use:
{{ form.structure.name }}
{{ form.structure.description}}
You can write custom form, override the save method and create Structure object manually there:
class FrameworkForm(forms.ModelForm):
structure_name = forms.CharField(required=True)
structure_description = forms.CharField(required=False)
class Meta:
model = SelectedFramework
fields = [
'structure_name', 'structure_description', 'selected'
]
def save(self, commit=False):
instance = super(FrameworkForm, self).save(commit=False)
structure = Structure(
name=self.cleaned_data.get('structure_name'),
description=self.cleaned_data.get('structure_description')
)
structure.save()
instance.structure = structure
instance.save()
return instance
Also add form_class = FrameworkForm to your view instead of fields = ['structure', 'selected']
EDIT:
Perhaps you want something like this:
<ul>
{% for structure in form.fields.structure.choices.queryset %}
<li>{{ structure.name }} - {{ structure.description }}</li>
{% endfor %}
</ul>
If you want to get fields by iterating in the template. You have to use-
{% for field in form %}
{{ field }}
{% endfor %}
don't have to use any dot notation to get the field. If you want to get the label of the field you can use {{ field.label}} usually before {{field}}

My "detailed" view page isn't working. The web page content is invisible

EDIT: I fixed the views.py with Av4t4r's code but it still shows no content. When I type something in voodoo.html it actually shows content, but all of the content inside the {% block content %} are not showing. Why is that?
Hello I am trying to make a simply gallery app where the first view (listview) is a list of all the persons (which are the objects), and when a user clicks on one it proceeds to the next page with a given pk/id key. But when it comes to that page... the content is blank. Here is what I have:
urls.py:
urlpatterns = [
url(r'^$', ListView.as_view(queryset=Images.objects.all(), template_name='imgboard/home.html')),
url(r'^imgboard/(?P<id>\d+)/$', views.voodoofunction, name='voodoofunction'),
]
views.py (I feel like this is where the problem is):
def voodoofunction(request, id=None):
instance = get_object_or_404(Moreimages, id=id)
context = { "object_list": instance, }
return render(request, "imgboard/voodoo.html", context)
models.py
class Images(models.Model):
name_person = models.CharField(max_length=70)
instagram = models.CharField(max_length=200)
img_url = models.CharField(max_length=500)
def __unicode__(self):
return self.name_person
class Meta:
verbose_name_plural = 'Images'
class Moreimages(models.Model):
key = models.ForeignKey(Images, on_delete=models.CASCADE)
img_url = models.CharField(max_length=500)
def __unicode__(self):
return str(self.key)
class Meta:
verbose_name_plural = "More Images"
listview_code.html
{% block content %}
{% for object in object_list %}
<p>{{object.name_person}}</p>
{% endfor %}
{% endblock %}
voodoo.html:
{% block content %}
<h2>{{ object.name_person}}<br></h2>
<h4>{{object.instagram}}</p></h4>
<br>
{% for object in object_list %}
<p><img src="{{object.img_url}}", width=350, height="360></img>"</p>
{% endfor %}
{% endblock %}
Your context has no "object" in it. And your "object_list" is an instance, not a list (so your for loop is doing nothing).

Database Error - no such column

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