I'm working with template variable on context, but no matter what i do, the context from view function is not displaying, what did i do wrong? - django-views

def index(request):
context = {
"name": "patrick",
"age": 23,
"country": "British",
}
return render(request, 'index.html', context)
then in html
hello,{{name}},you are {{age}} years old, and you are {{country}}

Related

TypeError: entry() missing 1 required positional argument: 'title' (Django Help)

With Django I'm creating an encyclopedia website similar to Wikipedia, for a class. I've played around with this for quite a while but still cannot solve this - I keep getting the error: entry() missing 1 required positional argument: 'title'
The error occurred when I clicked to create a new page on the site. This pertains to the function 'newpage' but I think the issue might be in the function 'entry.'
I did the exact steps (but using 'title') from this Stack Overflow suggestion but it did not work:
TypeError at /edit : edit() missing 1 required positional argument: 'entry'
In urls.py I've tried both:
path("wiki/<str:entry>", views.entry, name="entry"),
path("wiki/<str:title>", views.entry, name="entry"),
Just can't figure out how to get past the error. Any info is appreciated, as I'm new to Django.
urls.py file:
urlpatterns = [
path('admin/', admin.site.urls),
path("", views.index, name="index"),
path("wiki/<str:title>", views.entry, name="entry"),
path("newpage", views.entry, name="newpage"),
]
views.py file:
class CreateForm(forms.Form):
title = forms.CharField(label='title')
text = forms.CharField(label='text')
def index(request):
"""Homepage for website"""
return render(request, "encyclopedia/index.html", {
"entries": util.list_entries()
})
def entry(request, title):
""" Displays the requested entry page, if it exists """
entry_md = util.get_entry(title)
if entry_md != None:
# Title exists, convert md to HTML and return rendered template
entry_HTML = Markdown().convert(entry_md)
return render(request, "encyclopedia/entry.html", {
"title": title,
"entry": entry_HTML,
})
else:
# Page does not exist
return render(request, "encyclopedia/error.html", {
"title": title,
})
def newpage(request):
if request.method == "GET":
return render(request, "encyclopedia/newpage.html", {
"create_form": CreateForm(),
"title": title,
})
elif request.method == "POST":
form = CreateForm(request.POST)
if form.is_valid():
title = form.cleaned_data['title']
text = form.cleaned_data['text']
entries = util.list_entries()
if title in entries:
return render(request, "encyclopedia/newpageerror.html", {"message": "Page
already exists"})
else:
util.save_entry(title, text)
title = util.get_entry(title)
messages.success(request, f'New page "{title}" created successfully!')
return render(request, "encyclopedia/newpage.html")
The issue is you are saying that entry needs 2 parameters but only request is provided. You can change entry function to this:
def entry(request, title=None):
# Rest of your code
Here I am setting title=None as the default parameter, this will fix the issue you have now, but could cause other issues. I'm not sure exactly why there are 2 urls that go to entry.

How to dump the context in the templates?

How can I print all the keys in the context? For example I have a view like this:
def home(request):
return render(request, 'home.html', context={ 'first_name': 'Umut', 'last_name': 'Coşkun' })
How can I print all the context in the template? I'm searching for something like:
{{ all_the_context }}
And it will print:
{
"first_name": "Umut",
"last_name": "Coşkun"
}
Or if its an object instead of JSON, it's also okay.
Write in your views.py.
def home(request):
cont={ 'first_name': 'Umut', 'last_name': 'Coşkun' }
return render(request, 'home.html',context={'cont':cont})
and in template just use
{{cont}}

Why attribute of a dictionary works in template html through connection with codes in view.py ?

I am new to Django, and I am following a tutorial in which he writes something like
{%for post in posts %} {{post.author}}in the template html file. He describes that the template responds to the key 'posts'. To my understanding, post is a dictionary according to what he writes in view.py? How does it work?
posts = [
{
'author': 'JosephJ',
'title': 'Blog Post1',
'content': 'First post content',
'date_posted': 'August 27, 2018'
},
{
'author': 'RogerL',
'title': 'Blog Post2',
'content': 'Second post content',
'date_posted': 'August 28, 2018'
}
]
def home(request):
context = {
'posts': posts
}
return render(request, 'blog/home.html', context)
In the context ={ 'post_key': post_value }
The left portion is the key and the right portion is the value.
The key is passed into template and its value is a queryset in Django.
for ex: post_value = PostModel.objects.all() It is the queryset that is assigned to the "post_value"

Add list values to queryset - Django

I want to add a list object to the beginning of a queryset.
I have the following code for my ListAPIView:
def get_queryset(self):
obj1 = Books.objects.most_read_offset()[:30]
titles = Category.objects.most_publishes().values('title')
categories = []
for title in titles:
categories.append(title)
categories.insert(0, {'title': 'Popular'})
return chain(categories, obj1)
In my serializer, I use the following method to get the category url:
def get_category_url(self, obj):
request = self.context['request']
kwargs = {'slug': obj.category.slug}
return api_reverse('category_detail_api', kwargs=kwargs,
request=request)
When I try to compile the code, I get an error saying: 'dict' object has no attribute 'category'.
Does anyone know how to solve this?
EDIT:
This is what I would like my final result to look like:
[
{
"titles": "title_1", "title_2", "title_3",
},
{
"id": 62,
"category_url": "http://127.0.0.1:8000/categories/just-because/",
"slug": "XG84Jberu6",
},
{
"id": 63,
"category_url": "http://127.0.0.1:8000/categories/something/",
"slug": "YU65Zirvq7",
},
]
Your JSON result has, quite frankly, a terrible structure and the framework tools will not help you create it easily. Back-track and consider a JSON structure like this instead where you don't mix different kinds of data in the same list:
{
"titles": ["title_1", "title_2", "title_3"]
"books": [
{
"id": 62,
"category_url": "http://127.0.0.1:8000/categories/just-because/",
"slug": "XG84Jberu6",
},
{
"id": 63,
"category_url": "http://127.0.0.1:8000/categories/something/",
"slug": "YU65Zirvq7",
}
]
}
And return this from a simple api_view:
from rest_framework.decorators import api_view
from rest_framework.response import Response
#api_view()
def combined_view(request):
obj1 = Books.objects.most_read_offset()[:30]
titles = Category.objects.most_publishes().values_list('title', flat=True)
books_serializer = BookSerializer(obj1, context={'request': request}, many=True) # this is your previous serializer
return Response({
"titles": titles,
"books": books_serializer.data,
})
If your most_read_offset() queryset doesn't include a select_related('category') you should add this as well since your fetching the category for all book objects in get_category_url.

Transform function view in Class Based View Django + chartit

I have this function view.
How to transform this function in Class Based View?
In this case i use TemplateView?
def linechart(request):
ds = DataPool(
series=[{'options': {
'source': MonthlyWeatherByCity.objects.all()},
'terms': [
'month',
'houston_temp',
'boston_temp']}
])
cht = Chart(
datasource=ds,
series_options=[{'options': {
'type': 'bar',
'stacking': False},
'terms': {
'month': [
'boston_temp',
'houston_temp']
}}],
chart_options={'title': {
'text': 'Weather Data of Boston and Houston'},
'xAxis': {
'title': {
'text': 'Month number'}}})
return render_to_response('core/linechart.html', {'weatherchart': cht})
Return error
class MyTemplateView(TemplateView):
template_name = 'core/linechart.html'
def get_ds(self):
return DataPool(...)
def get_water_chart(self):
return Chart(datasource=self.get_ds() ...)
def get_context_data(self, **kwargs):
context = super(MyTemplateView, self).get_context_data(**kwargs)
context['weatherchart'] = self.get_water_chart()
return context
in urls should be something like this
url(r'^$', MyTemplateView.as_view(), name='index'),
I would think your best bet would be to use a generic View instead of a template since it's so easy to make the switch. Something like:
from django.shortcuts import get_object_or_404
from django.shortcuts import render
from django.views.generic import View
class LinechartView(View):
def get(self, request, *args, **kwargs):
ds = DataPool(
series=[{'options':
{'source': MonthlyWeatherByCity.objects.all()},
'terms': [
'month',
'houston_temp',
'boston_temp']}
])
cht = Chart(
datasource=ds,
series_options=[
{'options': {
'type': 'bar',
'stacking': False
},
'terms': {
'month': [
'boston_temp',
'houston_temp']
}}],
chart_options={
'title': {
'text': 'Weather Data of Boston and Houston'},
'xAxis': {
'title': {
'text': 'Month number'
}}})
return render(request, {'weatherchart': cht})
# Doing it like this also allows flexibility to add things like a post easily as well
# Here's an example of how'd you go about that
def post(self, request, *args, **kwargs):
# Handles updates of your model object
other_weather = get_object_or_404(YourModel, slug=kwargs['slug'])
form = YourForm(request.POST)
if form.is_valid():
form.save()
return redirect("some_template:detail", other_weather.slug)
I went ahead and formatted to the best of my abilities trying to view it within stackoverflow. Why not use an IDE like pycharm to make life easy (at least for formatting)?