Can't pass model data in templates django - python

I want to pass data from 'About' model to html template, but I can't figure out what is going wrong.. as I am new to Django. I gave lot of time to it.. but it still remains the same:
from django.db import models
class About(models.Model):
image = models.ImageField(upload_to = 'pics')
desc = models.TextField()
views.py
from django.shortcuts import render
from .models import About
def index(request):
abt = About.objects.all()
return render(request,'home/index.html',{abt:'abt'})
html
<img src="{{abt.image}" alt="profile photo">
<p>{{abt.desc}}</p>

{abt:'abt'}
No, it's other way around.
{'abt':abt}
Label on the left, data on the right.
If you want to get a single instance you can use first method
<p>{{abt.first.desc}}</p>
or in the similar way, provide only the first object
return render(request,'home/index.html',{'abt': abt.first()})

Related

Django renew field from database,calculated field in Database

Newby in django, have two question, can't find needed info.
1) I have database (SQLite) which have table scale_calibration and field weight. Other application rewrite value in field weight 1-2 times per second. Is there possibility in Django to renew this field without renew browser (F5)?
models.py:
from django.db import models
class Calibration(models.Model):
mean_weight = models.FloatField(editable=True)
hours_to_export = models.PositiveIntegerField(default=4, editable=True)
weight = models.FloatField(editable=True)
admin.py:
from django.contrib import admin
from .models import Calibration
# Register your models here.
admin.site.register(Calibration)
2) I try follow that link to make easy calculated field (that will be write to database when save), but i have no results and no error, don't understand where i did mistake.
models.py:
from django.db import models
class Calibration(models.Model):
mean_weight = models.FloatField(editable=True)
hours_to_export = models.PositiveIntegerField(default=4, editable=True)
weight = models.FloatField(editable=True)
calibration_factor = models.FloatField(editable=True)
#property
def get_calibration(self):
return self.weight/self.mean_weight
def save(self, *args, **kwarg):
self.calibration_factor = self.get_calibration()
super(Calibration, self).save(*args, **kwarg)
Please help with advise.
As #david-alford mention, AJAX is a good solution to your problem. This simply writing JavaScript in your templates that make a request every n seconds and update your webpage, also you will need a new endpoint in your Django app that provides the update values from your model to this requests to be repeated.
If this sounds weird or complicated, take a look at some AJAX examples with Django, and feel free to ask more specific questions for clarifications.

How to query Django model from views.py file?

I have a model named Search in my models.py file. I have made migrations and everything is working totally fine except one problem. In my views.py file I have created one variable called var1 which queries "search_query" field into the database, but unfortunately, it couldn't assign that variable.
Please help me how to access my model to work this line,
var1 = Search.objects.latest('search_query')
Here is my models.py file,
from django.db import models
class Search(models.Model):
search_query = models.CharField(max_length=64)
views.py file,
from django.shortcuts import render, redirect
import requests
from git_profile.forms import SearchForm
from git_profile.models import Search
def index(request):
var1 = Search.objects.latest('search_query')
EDIT:
I want to replace 'var1' with this replacement
python
user_profile = requests.get('https://api.github.com/users/{0}'.format(str(v‌​‌​ar1)))
content = dict()
content['user'] = user_profile.json()
but var1 can not be replaced by replacement field and API gives me weird error
There is an useful search using boolean operator that you can use from django.db.models import Q # filter using operators '&' or '|'.
Example:
class RestaurantListView(ListView):
def get_queryset(self):
slug = self.kwargs.get("slug")
if slug:
queryset = RestaurantLocation.objects.filter(
Q(category__iexact=slug) |
Q(category__icontains=slug)
)
else:
queryset = RestaurantLocation.objects.all()
return queryset
For more information of using queryset, refer to https://docs.djangoproject.com/en/1.11/ref/models/querysets/
https://simpleisbetterthancomplex.com/tutorial/2016/11/28/how-to-filter-querysets-dynamically.html
Cheers
Henry
In your view you most create a Dictionary and assign the select variable to a property and the pass the dictionary to the view in this way:
def index(request):
var1 = Search.objects.latest('search_query').search_query
context = {'property': var1 }
return render(request, 'YOURVIEW', context)
and then access to the dictionary in the view:
{{ property.your_key}}
See more information in the Django App part 3 tutorial: https://docs.djangoproject.com/en/1.11/intro/tutorial03/
I have had a hard time understanding what you're trying to do, however these are typical use cases.
from django.shortcuts import render, redirect
import requests
from git_profile.forms import SearchForm
from git_profile.models import Search
def index(request):
var1 = Search.objects.all()
# do something with variable var1
# another example
def index(request, search_query):
# as you can notice I'm expecting the parameter search_query, so make sure that in urls.py you define it properly.
var1 = Search.objects.filter(search_query=search_query)
edit as per Klaus D.'s comment:
you're also missing a dot
def index(request):
var1 = Search.objects.latest('search_query').search_query
# do something with variable var1

Saving a Form to a Database (Django Python)

In my Django app I have a form with an email and a text area that needs to go into the database but am struggeling to do so. At the moment I have 2 different solutions in my code:
OK, let me write this from the beginning. Maybe it is better if you do the below steps with me now for an exercise.
Now, the correct way to do the above task (I try to clear this subject a little more because I know that many other people will read this problem and they can learn from this too. And it is important to understand it for your future tasks.
If you want to create a Form and you know that you will want to save the submitted data from that Form to the database, then of course you should start the whole task with creating a Model, thus a table for that in the database.
So, first you create a Model (which you will call ie. “Questions” in this case, since you want to call your Form ie. QuestionForm, so it is better if your Model and table will be related to that with their names too).
So your Model will be in your models.py file:
from django.db import models
# Create your models here.
class Questions(models.Model):
contact_email = models.EmailField(max_length=60)
question = models.CharField(max_length=600)
Then you will create a ModelForm from this in your forms.py file the following way:
from django import forms
from django.forms import ModelForm, Textarea
from . import models
class QuestionForm(ModelForm):
class Meta:
model = models.Questions
fields = ['contact_email', 'question']
widgets = {
'question': Textarea(attrs={'cols': 40, 'rows': 20}),
}
Then you create your view function in your views.py file:
from django.shortcuts import render, redirect
from . import forms
from . import models
from django.http import HttpResponse
def get_question(request):
form = forms.QuestionForm()
if request.method == 'POST':
form = forms.QuestionForm(request.POST)
if form.is_valid():
form.save()
return redirect(‘success.html’) # or you redirect anywhere you want to
else:
form = forms.QuestionForm()
return render(request, 'contact.html', {'form':form})
And at this point you will create your urlpattern in your urls.py to call the get_question view function. It will look like the following:
from django.conf.urls import url
from basic_app import views
# app_name = 'basic_app' # Important for referencing urls in HTML pages(use your own app_name here). But for this example task this is not important.
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^questions/', views.get_question, name="questions_page"),
]
I hope I did not confuse you more. If you do the above steps, it should work for you. And you can create as many Forms as you want with the above steps and saving them easily in the Database.
The only other thing you have to have to run the above, is your 'contact.html' page which you already have and you already created.
(do not forget to run: python manage.py migrate)
So, I hope that you see, in the above example you do not mismatch fields and field names, and you do not get confused about what to save where. Since the Model and the Form is working together and created together with the same field names.

Django CMS custom plugin load data from cms_title

I want to create a custom plugin for Django CMS. As the guide was showing, I created some examples. But now the goal is to create a plugin that will get the data from (mysql) database. It will load all titles that belong to the menu, because I want to have some similar to table of contents.
To get data from an custom model, the code goes like this:
models.py:
from cms.models.pluginmodel import CMSPlugin
from django.db import models
class Hello(CMSPlugin):
guest_name = models.CharField(max_length=50, default='Guest')
cms_plugins.py:
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
from django.utils.translation import ugettext_lazy as _
from .models import Hello
class HelloPlugin(CMSPluginBase):
model = Hello
name = _("Hello Plugin")
render_template = "hello_plugin.html"
cache = False
def render(self, context, instance, placeholder):
context = super(HelloPlugin, self).render(context, instance, placeholder)
return context
plugin_pool.register_plugin(HelloPlugin)
But as cms_title belongs to the Django-CMS by default, what options are possible here? Where can I find the definition of CMS model with name Title? Would setting it to CMSPlugin instance be a bad way?
Well, after few hours of struggling with this case, I finally succeeded to resolve my problem.
First of all, to answer the part of the question with CMS model and parameter title (in db: cms_title). Creating a new model with the FK to CMS title is the right way.
In models.py:
class TitlePlugin(CMSPlugin):
title = models.ForeignKey(Title)
As next, you need to import it to cms_plugins.py, so it will look like this:
from .models import TitlePlugin
class MyTitlePluginClass(CMSPluginBase):
model = TitlePlugin
render_template = "titles.html"
cache = False
As you see, the model that we load is TitlePlugin, we defined in models.py (which has FK to original cms_title).
And now, render it:
def render(self, context, instance, placeholder):
context = super(MyTitlePluginClass, self).render(context, instance, placeholder)
return context
But my goal was to load it into template for the purpose of 'table of contents', right? So I had to change some things.
I removed models.py content (not needed!)
The new cms_plugins.py had modifications too:
first:
from cms.models.pagemodel import Page
#we import the Page model
and the renewed class:
class MyTitlePluginClass(CMSPluginBase):
model = CMSPlugin
render_template = "titles.html"
cache = False
def render(self, context, instance, placeholder):
pages = Page.objects.filter(in_navigation=True, publisher_is_draft=False)
#context = {
#'pages' : pages,
#}
# edit: append to 'pages' existing list!
context['pages'] = pages
context = super(MyTitlePluginClass, self).render(context, instance, placeholder)
return context
plugin_pool.register_plugin(MyTitlePluginClass)
And in the template, we simply print it using for loop
titles.html:
{% for page in pages %}
<div class="panel callout ">
{{ page }}
</div>
{% endfor %}

How do I get POST data from a free text field?

Doing a modified version of the polls tutorial. Comments work with the database when I go in the python manage.py shell but I can't get it to actually read the post data. Any time I post a comment, the page re-renders but no comment in the database.
Here are my models for an individual Entry and a Comment
import datetime
from django.db import models
from django.utils import timezone
from django.forms import ModelForm
class Entry(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
pub_date = models.DateTimeField('date published')
class Comment(models.Model):
entry = models.ForeignKey(Entry)
comment = models.TextField()
comment_date = models.DateTimeField()
In the Python shell, I'm able to create comments (that show up in the admin) perfectly.
>>> from blog.models import Entry, Comment
>>> e = Entry.objects.get(pk=1)
>>> from django.utils import timezone
>>> e.comment_set.create(comment="isn't it pretty to think so?", comment_date=timezone.now())
<Comment: isn't it pretty to think so?>
In the detail.html view of each blog entry, a user can add a comment.
<h1>{{ entry.title }}</h1>
<p>{{ entry.body }}</p>
<p>{{ entry.tags_set.all }}</p>
<form action="{% url 'blog:comment' entry.id %}" method="post">
{% csrf_token %}
<textarea name="comment101" style="width:300px; height: 70px; maxlength="300"; display:none;">
</textarea></br>
<input type="submit" name="comment101" value="Add comment" />
</form>
Views for detail and comment:
from django.utils import timezone
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.core.urlresolvers import reverse
from blog.models import Entry, Tags, Comment
def detail(request, entry_id):
entry = get_object_or_404(Entry, pk=entry_id)
return render(request, 'entries/detail.html', {'entry': entry})
def comment(request, entry_id):
p = get_object_or_404(Entry, pk=entry_id)
add_comment = request.POST['comment101']
#get input name comment from POST data
p.comment_set.create(comment="add_comment", comment_date=timezone.now())
return HttpResponseRedirect(reverse('blog:detail', args=(p.id)))
I've exhausted all I know. I tried adding name='comment101' every input/form in detail.html and my comment view replicates exactly what I did in the Python shell.
Lastly, if anyone could point me to something to debug code involving POST data (for Mac), that'd be helpful. Thank you.
I recommend you to use request.POST.get to get post data:
add_comment = request.POST.get('comment101',None)
Where None is the default value if nothing is passed. Then in the following lines you should check whether add_comment is None or not by a simple if statement:
if add_comment is not None:
#do the work
I also recommend you to control the request type with request.method == 'POST'.
Then you can create the comment:
comment = Comment()
comment.comment = add_comment;
comment.comment_date = timezone.now()
comment.entry = p
comment.save()
To debug, I personally use print keyword. If you would like to see all post data you can iterate and print them. When you use print keyword or method (for python 3) you can see the output in from ./manage.py runserver outputs.
for key, value in request.POST.iteritems():
print key, value
I would use
c = Comment(comment=add_comment, comment_date=timezone.now(), entry=p)
c.save()
That might be of some use.
Also if you want to debug code it is best to place
import pdb; pdb.set_trace()
which gives you interactive console wherever you want it.
In case you want to use something better use ipdb (pip install ipdb)
import ipdb; ipdb.set_trace()

Categories

Resources