DRF Create: render_to_string() loses it's context variables when the Response is returned - python-3.x

Background
I want to create and render replies without the need to refresh the page. I know this can be done by submitting the form using AJAX or Fetch(), and use the returned response to append to the bottom of the comment list. I am trying to accomplish this using DRF and AJAX. I opted in to DRF HTMLRenderer + Django render_to_string() so I do not have to create a JS template literal to render the template from JSON, and it would also be a lot easier for me to make any template changes if I just let the Django templating system do it for me.
Problem
My response is not populating my template with context variables, despite me passing in the context to the built in render_to_string(). The chances of render_to_string() being at fault is very low, and I am honestly not sure how to resolve this. I also tried switching out the render_to_string() with render() to see if that would somehow fix the problem. However, the problem still remained.
I know this because of the following two attribute errors when viewing the response from the console:
'str' object has no attribute 'is_authenticated'
Reverse for 'profile_detail' with arguments '('',)' not found. 1 pattern(s) tried: ['account/user/(?P<slug>[^/]+)/$']
Both of which would not be happening if the context was being evaluated in my template.
The actual reply itself is created and visible if I manually refresh the page after the AJAX post.
Information
There does not seem to be a problem with the actual context, because the break point shows the expected results (... is me replacing the actual text for brevity):
{'reply': <Reply: Reply object (47527)>, 'post': <Post: ....>, 'recipient': <Profile: ....>}}
Edit:
When I print print(response['render_reply']) the template is populated, however once it returns in return Response(response), the template is no longer populated with the reply object.
Questions
Is my problem happening with the render_to_string(), or is there something else at fault?
Am I on the right track to sending and rendering replies? Is there anything that can be improved? (code review)
So the problem is most likely occurring here, but that would be really odd because what are the chances of a built in function not working?
response['render_reply'] = render_to_string(
template_name=self.template_name, context=context, request=request
)
Relevant code
Viewset
I created my own action because I wasn't quite sure how to accomplish this with the default create().
class ReplyActionViewSet(viewsets.ModelViewSet):
queryset = Reply.objects.all()
serializer_class = ReplySerializer
permission_classes = [IsAuthenticated]
renderer_classes = [JSONRenderer, TemplateHTMLRenderer]
template_name = "post/partials/render-reply.html"
def get_queryset(self):
return self.queryset.filter(user=self.request.user)
#action(detail=True, methods=['post'])
def create_reply(self, request, pk=None):
response = {}
post = get_object_or_404(
Post.public_or_member_objects.all(), pk=pk
)
serializer = ReplySerializer(data=request.POST)
if serializer.is_valid():
...
reply = Reply.objects.create(**data)
...
context = {'reply': reply, 'post': post, 'data': {"post": post, "recipient": reply.recipient}}
response['render_reply'] = render_to_string(
template_name=self.template_name, context=context, request=request
)
return Response(response)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Snippet of the reply template where one of the issues is happening:
<div class="d-flex flex-row align-items-center">
<div class="avatar avatar-sm me-2" style="background-color:{{ post.user.avatar_color }};">
{{ reply.user.nickname|slice:1 }}
</div>
<a href="{% url "profile_detail" reply.user.username %}" class="text-decoration-none">
<span style="font-weight: 500; color:{{ post.user.avatar_color }};">{{ reply.user.nickname }}</span>
</a>
</div>
And here is my JS:
'use strict';
$(document).on("submit", ".js-reply-form", function (event) {
event.preventDefault();
const form = $(this);
const url = form.attr('action');
$.ajax({
type: "POST",
url: url,
dataType: 'html',
data: form.serialize(),
success: function (data) {
form.trigger('reset');
},
error: function (response) {
console.log(response);
console.log("failed!");
},
});
});
Included trace:
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/api/v1/reply-actions/42874/create_reply/
Django Version: 3.2.7
Python Version: 3.10.2
Installed Applications:
Template error:
In template C:\Users\...\Documents\Repo\drf_project\journal\templates\journal\partials\reply-render-reply.html, error at line 36
'str' object has no attribute 'is_authenticated'
26 : </div>
27 :
28 : <div>
29 : {% if reply.user.is_premium %}
30 : <span title="{% trans "drf_project Premium" %}" class="px-1">
31 : <i class="fas fa-crown fa-fw"></i>
32 : </span>
33 : {% endif %}
34 :
35 : <span title="{% trans "X ratio" %}" class="px-1">
36 : <i class="fas fa-percentage"></i> {{ reply.user|get_X_ratio }}
37 : </span>
38 : </div>
39 : </div>
40 :
41 : <!-- Reply body -->
42 : <div>
43 : <div class="small text-muted my-2">{{ reply.date }}</div>
44 :
45 : <!-- Quoted content -->
46 : {% if reply.y_row_id %}
Traceback (most recent call last):
File "C:\Users\...\Documents\Repo\drf_project\venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\...\Documents\Repo\drf_project\venv\lib\site-packages\django\core\handlers\base.py", line 204, in _get_response
response = response.render()
File "C:\Users\...\Documents\Repo\drf_project\venv\lib\site-packages\django\template\response.py", line 105, in render
self.content = self.rendered_content
File "C:\Users\...\Documents\Repo\drf_project\venv\lib\site-packages\rest_framework\response.py", line 70, in rendered_content
ret = renderer.render(self.data, accepted_media_type, context)
File "C:\Users\...\Documents\Repo\drf_project\venv\lib\site-packages\rest_framework\renderers.py", line 167, in render
return template.render(context, request=request)
File "C:\Users\...\Documents\Repo\drf_project\venv\lib\site-packages\django\template\backends\django.py", line 61, in render
return self.template.render(context)
File "C:\Users\...\Documents\Repo\drf_project\venv\lib\site-packages\django\template\base.py", line 170, in render
return self._render(context)
File "C:\Users\...\Documents\Repo\drf_project\venv\lib\site-packages\django\test\utils.py", line 100, in instrumented_test_render
return self.nodelist.render(context)
File "C:\Users\...\Documents\Repo\drf_project\venv\lib\site-packages\django\template\base.py", line 938, in render
bit = node.render_annotated(context)
File "C:\Users\...\Documents\Repo\drf_project\venv\lib\site-packages\django\template\base.py", line 905, in render_annotated
return self.render(context)
File "C:\Users\...\Documents\Repo\drf_project\venv\lib\site-packages\django\template\base.py", line 988, in render
output = self.filter_expression.resolve(context)
File "C:\Users\...\Documents\Repo\drf_project\venv\lib\site-packages\django\template\base.py", line 698, in resolve
new_obj = func(obj, *arg_vals)
File "C:\Users\...\Documents\Repo\drf_project\journal\templatetags\navbar_tags.py", line 15, in get_X_ratio
if user.is_authenticated:
Exception Type: AttributeError at /api/v1/reply-actions/42874/create_reply/
Exception Value: 'str' object has no attribute 'is_authenticated'

Please post the whole trace for the 1st error
<str> object has no ...
Your 2nd error means that in
<a href="{% url "profile_detail" reply.user.username %}"
the username is empty.

The solution was honestly quite straightforward. response['render_reply'] evaluated to {'render_reply':'long string'} which is JSON.
So I needed to change the dataType in my AJAX post to use json instead of html.
I also just passed in the rendered template so I did not have to call data["render_reply"].
context = {
'reply': reply,
'post': post,
'recipient': reply.recipient
}
rendered_template = render_to_string(
template_name='journal/partials/reply-render-reply.html',
context=context,
request=request
)
return Response(rendered_template)

Related

Flask. Processing a form on another page. TypeError: The view function did not return a valid response

Good day!
I'm new to Python and Flask
I am trying to render a form on another page when I apply this construction :
#app.route('/tools', methods=['POST', 'GET'])
def tools():
"""Form Create Users"""
createadduser_form = ToolsAddUser()
return render_template("tools.html", title='Admin Tools', **locals())
#app.route('/createuser', methods=["GET", "POST"])
def createuser():
if request.method == 'POST':
adduser_clientid = request.form["adduser_clientid"]
adduser_value = request.form["adduser_value"]
create(adduser_clientid, adduser_value)
return redirect("tools")
But in the event that I use another one with field validation, it does not work:
#app.route('/tools', methods=['POST', 'GET'])
def tools():
createadduser_form = ToolsAddUser()
return render_template("tools.html", title='Admin Tools', **locals())
#app.route('/createuser', methods=["GET", "POST"])
def createuser():
createadduser_form = ToolsAddUser()
if createadduser_form.validate_on_submit():
adduser_clientid = request.form["adduser_clientid"]
adduser_value = request.form["adduser_value"]
create(adduser_clientid, adduser_value)
return redirect("tools")
I understand the problem here:
if createadduser_form.validate_on_submit():
if request.method == 'POST':
In the first option, when you click on the button, the script works as needed (the script is launched powershell, so do not pay attention to the names of the variables, this is a test)))) everything works well
In the second option, it shows an error:
I can't understand what the problem is, little experience. I would be very grateful for your help.
http://127.0.0.1:5000/createuser
TypeError
TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement.
Traceback (most recent call last)
File "E:\Project\web\venv\lib\site-packages\flask\app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "E:\Project\web\venv\lib\site-packages\flask\app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "E:\Project\web\venv\lib\site-packages\flask\app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "E:\Project\web\venv\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "E:\Project\web\venv\lib\site-packages\flask\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "E:\Project\web\venv\lib\site-packages\flask\app.py", line 1953, in full_dispatch_request
return self.finalize_request(rv)
File "E:\Project\web\venv\lib\site-packages\flask\app.py", line 1968, in finalize_request
response = self.make_response(rv)
File "E:\Project\web\venv\lib\site-packages\flask\app.py", line 2098, in make_response
"The view function did not return a valid response. The"
TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement.
Below, just in case, the form itself...
class ToolsAddUser(FlaskForm):
adduser_clientid = StringField('Client ID',
validators=[DataRequired()],
render_kw={'class': 'form-control',
'placeholder': 'Client ID'})
adduser_value = StringField('Value',
validators=[DataRequired()],
render_kw={'class': 'form-control',
'placeholder': 'Value'})
submitbuttonuser = SubmitField('Submit',
render_kw={'class': 'btn btn-dark'})
I apologize for the inaccuracies in the wording
<form action="/createuser" method="post">
 <div class="form-group form shadow">
 <label for="">
 <h5>Add User</h5>
 </label>
 {{ createadduser_form.adduser_clientid }}<br>
 {{ createadduser_form.adduser_value }}<br>
 <input type="text" class="form-control" placeholder="Example input" style="visibility: hidden;"><br>
 {{ createadduser_form.submitbuttonuser }}
 </div>
</form>
You're not returning a response when you navigate to /createuser, which will be a GET. You are only returning a response within if createadduser_form.validate_on_submit():, which will only handle the POST call.
I assume you'll be wanting to render the form you've created, like:
return render_template("createuser.html")
Thank you all who paid attention to this topic, I have solved my problem. The thing is that I didn't add the cars page to the html
It turns out that the CSRF check did not pass my request further than the page
{{ {{ create add user_form.hidden_tag () }}
For this check, it is required
if create add user_form.validate_on_submit():
Week, week, week

pass a parameter to a view function (form) in a for loop to populate form flask wtforms sqlalchemy

I want to be able to display the rows of a database model on my web page as an updatable prepopulated form! I can display the rows on the page easily and I can add a link to each to open a seperate page to edit each row, I can also display each row with the update form, but I cant display the form populated. here is my code:
#bp.route('/stock', methods=['GET', 'POST'])
#bp.route('/stock/<int:id>', methods=['GET', 'POST'])
#login_required
def stock(id=None):
if id is not None:
obj = Stock.query.get_or_404(id)
form = AddStockForm(request.form, obj=obj)
if form.validate_on_submit():
form.populate_obj(obj)
db.session.commit()
return redirect(url_for('stock.stock'))
else:
form = AddStockForm()
page = request.args.get('page', 1, type=int)
stock = Stock.query.order_by(Stock.id.desc()).paginate(
page, current_app.config['ITEMS_PER_PAGE'], False)
next_url = url_for('stock.stock', page=stock.next_num) \
if stock.has_next else None
prev_url = url_for('stock.stock', page=stock.prev_num) \
if stock.has_prev else None
return render_template('stock/stock.html',form=form, title=Stock, stock=stock.items,
next_url=next_url, prev_url=prev_url)
and the stock.html code:
{% extends "base.html" %}
{% block content %}
<div class="main">
<h2>Stock</h2>
<div class="books">Upload Stock csv
</div>
<div class="books">Add a new Item</div>
{% for s in stock %}
{% include 'stock/_stock.html' %}
{% endfor %}
</div>
_stock.html code:
<div class="stock">
<div class="c0"><img src="{{ s.image_url }}" alt="{{ s.image_filename }}"></div>
<form action="{{ url_for('stock._stock', id=s.id) }}" method="post",
enctype="multipart/form-data">
{{ form.hidden_tag() }}
<div>SKU<BR> {{ s.id }} </div>
<div>Date of Purchase<br>{{ form.date(class="input") }}</div>
<div>Description<br>{{ form.description(class="input") }}</div>
<div>Market<br>{{ form.event(class="input") }}</div>
<div>Purchase Price<br>{{ form.achat(class="input") }}</div>
<div>Sale Price<br>{{ form.vente(class="input") }}</div>
<div>Sold<br>{{ form.sold(class="input") }}</div>
<div>{{ form.submit(class="submit") }}</div>
</form>
</div>
on google developer tools each form shows stock/4 or 3 but this does not seem to then populate the form. there are no error messages.
thanks in advance for any help.
regards Paul
EDIT
hi #Greg Cowell, Thank you for your help, I have addapted your code but I Get this error
File "/var/www/accounts/bdf/templates/base.html", line 30, in root
</body>
File "/var/www/accounts/env/lib/python3.7/site-packages/jinja2/runtime.py", line 262, in call
return __obj(*args, **kwargs)
File "/var/www/accounts/env/lib/python3.7/site-packages/flask/helpers.py", line 370, in url_for
return appctx.app.handle_url_build_error(error, endpoint, values)
File "/var/www/accounts/env/lib/python3.7/site-packages/flask/app.py", line 2215, in handle_url_build_error
reraise(exc_type, exc_value, tb)
File "/var/www/accounts/env/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/var/www/accounts/env/lib/python3.7/site-packages/flask/helpers.py", line 358, in url_for
endpoint, values, method=method, force_external=external
File "/var/www/accounts/env/lib/python3.7/site-packages/werkzeug/routing.py", line 2020, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.BuildError: Could not build url for endpoint 'stock.stock'. Did you forget to specify values ['id']?
[pid: 29588|app: 0|req: 1/1] 192.168.0.13 () {48 vars in 1095 bytes} [Sun Nov 17 09:26:58 2019] GET /index =>
here is the adapted code:
#bp.route('/stock/stock/<int:id>/', methods=['GET', 'POST'])
#login_required
def stock(id=None):
if id is not None:
group = current_user.group()
try:
stock = Stock.query.filter_by(group=group, id=id).one()
except NoResultFound:
flash('Invalid account.')
return redirect(url_for('stock.add_stock'))
accounts = current_user.group().stock
form = AddStockForm()
form.stock_id.default = stock.id
if form.validate_on_submit():
if form.modify.data:
for s in stock:
if (
item.id == form.stock_id.data and
item.id != form.stock_id.default
):
flash('Another account already has this name.')
return redirect(url_for('stock.add_stock', id=id))
stock.id = form.stock_id.data
db.session.add(stock)
db.session.commit()
form.process() # Do this after validate_on_submit or breaks CSRF token
else:
form = AddStockForm()
page = request.args.get('page', 1, type=int)
stock = Stock.query.order_by(Stock.id.desc()).paginate(
page, current_app.config['ITEMS_PER_PAGE'], False)
next_url = url_for('stock.stock', page=stock.next_num) \
if stock.has_next else None
prev_url = url_for('stock.stock', page=stock.prev_num) \
if stock.has_prev else None
return render_template('stock/stock.html',form=form, title=Stock, stock=stock.items,
next_url=next_url, prev_url=prev_url)
SECOND EDIT
I added this to the top of the view function:
#bp.route('/stock', methods=['GET', 'POST'])
which got rid of the above error, I then got a similar error for the "stock.html code"
{% for s in stock %}
{% include 'stock/_stock.html' %}
{% endfor %}
which I changed to:
{% include {{ url_for('stock._stock', id=['s.id']) }} %}
Which gives me the following error:
jinja2.exceptions.TemplateSyntaxError: expected token ':', got '}'
I use a different method for prepopulating forms.
In summary, I set the default for each form field and process the form before rendering. In the example below I set the value for the account_name field default using form.account_name.default = account.accname and then call form.process() before rendering the form.
#web.route('/accounts/modify/<int:accno>/', methods=['GET', 'POST'])
#login_required
def modify_account(accno):
"""
Modify or delete accounts.
Return a form for modifying accounts or process submitted
form and redirect to Accounts HTML page.
"""
group = current_user.group()
try:
account = Account.query.filter_by(group=group, accno=accno).one()
except NoResultFound:
flash('Invalid account.')
return redirect(url_for('.accounts_page'))
accounts = current_user.group().accounts
form = ModifyAccountForm()
form.account_name.default = account.accname
if form.validate_on_submit():
if form.modify.data:
for item in accounts:
if (
item.accname == form.account_name.data and
item.accname != form.account_name.default
):
flash('Another account already has this name.')
return redirect(url_for('.modify_account', accno=accno))
account.accname = form.account_name.data
db.session.add(account)
db.session.commit()
elif form.delete.data:
for transaction in current_user.group().transactions:
if transaction.account == account:
unknown_account = Account.query.filter_by(
group=current_user.group(), accname='Unknown').one()
transaction.account = unknown_account
db.session.add(transaction)
db.session.commit()
db.session.delete(account)
db.session.commit()
elif form.cancel.data:
pass
return redirect(url_for('.accounts_page'))
form.process() # Do this after validate_on_submit or breaks CSRF token
return render_template(
'modify_account.html', form=form, accno=accno, menu="accounts")
To make an HTML page which has a form for each record and an individual submit button for each record, you need to create multiple forms in your view/route function and then loop through them all in your HTML template.
View/route:
#web.route('/stocks', methods=['GET', 'POST'])
def stocks():
"""Return Stocks HTML page."""
stocks = Stock.query.all()
forms = []
for stock in stocks:
form = ModifyStockForm()
form.stock_id.default = stock.stock_id
form.stock_name.default = stock.stock_name
forms.append(form)
for form in forms:
if form.validate_on_submit():
if form.modify.data:
stock = Stock.query.filter_by(stock_id=form.stock_id.data).one()
stock.stock_name = form.stock_name.data
db.session.add(stock)
db.session.commit()
elif form.delete.data:
stock = Stock.query.filter_by(stock_id=form.stock_id.data).one()
db.session.delete(stock)
db.session.commit()
return redirect(url_for('.stocks'))
form.process() # Do this after validate_on_submit or breaks CSRF token
return render_template('stocks.html', forms=forms, stocks=stocks)
Template:
<h2>Stocks:</h2>
{% for form in forms %}
<form method="post" role="form" enctype="multipart/form-data">
{{ form.hidden_tag() }}
{{ form.stock_id }}
{{ form.stock_name }}
{{ form.modify }}
{{ form.delete }}
</form>
{% endfor %}
I've put a complete example in this repo: Example of multiple forms on a single page

Django, update value with Queryset

Im trying to update 1 value with a button on the frontend. But this is not working.
First some code snippets.
models.py
DRAFT = "D"
PUBLISHED = "P"
CLOSED = "C"
STATUS = (
(DRAFT, _("Draft")),
(PUBLISHED, _("Published")),
(CLOSED, _("Closed")),
)
class Item(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, related_name="itemauthor", on_delete=models.SET_NULL)
slug = models.SlugField(max_length=80, null=True, blank=True)
status = models.CharField(max_length=1, choices=STATUS, default=DRAFT)
...
views.py
class DeleteItemView(ListView, UpdateView):
def get_queryset(self):
Item.objects.filter(pk=self).update(status='C')
urls.py
urlpatterns = [
...
url(r'^delete/(?P<pk>\d+)/$', DeleteItemView.as_view(), name='delete_article'),
...
]
.html
a class="btn btn-success" href="{% url 'offers:delete_article' object.pk %}" title="{% trans 'Delete Item' %}"><i class="fa fa-pencil" aria-hidden="true"></i> {% trans 'Delete Item' %}</a>
But this will not work, I jump from one error to the next.
I get this error message from Django
int() argument must be a string, a bytes-like object or a number, not 'DeleteItemView'
Request Method: GET
Request URL: http://127.0.0.1:8000/offers/delete/2/
Django Version: 2.2.2
Exception Type: TypeError
Exception Value:
int() argument must be a string, a bytes-like object or a number, not 'DeleteItemView'
Exception Location: /home/PycharmProjects/base_camp/venv/lib/python3.7/site-packages/django/db/models/fields/__init__.py in get_prep_value, line 966
Python Executable: /home/PycharmProjects/base_camp/venv/bin/python
Python Version: 3.7.3
where do I make the mistake here?
The pk can not be self, it should be self.kwargs['pk']. That being said, it probably makes more sense to use a DeleteView here, and patch the delete function, like:
from django.views.generic import DeleteView
class DeleteItemView(DeleteView):
model = Item
def delete(self, request, *args, **kwargs):
self.object = self.get_object()
success_url = self.get_success_url()
self.object.status = 'C'
self.object.save()
return HttpResponseRedirect(success_url)
Note that you will need to make a POST or DELETE request in order to delete the object, so you can make a mini form for example with:
<form action={% url 'offers:delete_article' object.pk %}" method="post">
<button type="submit" class="btn btn-success" href=" title="{% trans 'Delete Item' %}"><i class="fa fa-pencil" aria-hidden="true"></i> {% trans 'Delete Item' %}</button>
</form>

Is it possible to use Template Tags in Django 1.11 to get around a "NoneType" Error?

I am using template tags to present data that has been derived from class objects on the back end. Both class objects require inputs from the user to work and if the input is not valid they return None.
I need to present a difference calculation of two of the objects on the page (it does not need to be saved to the database). So I have installed mathfilters https://pypi.python.org/pypi/django-mathfilters to do the subtraction which worked if there is user input but does not work if I am just navigating to the page or no user input.
Template HTML:
<tr>
<td>Interest</td>
<td class="data">${{int_numbers.get_sum_int_daily_numbers | intcomma }}</td>
<td class="data">${{int_goals.get_div_goalsint_wdays | intcomma }}</td>
<td class="data"><font class="red">
${{ int_numbers.get_sum_int_daily_numbers|sub:int_goals.get_div_goalsint_wdays | intcomma }}
</font>
</td>
</tr>
Which gives me this error:
Traceback:
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in _resolve_lookup
882. current = current[bit]
During handling of the above exception ('NoneType' object is not subscriptable), another exception occurred:
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in _resolve_lookup
890. current = getattr(current, bit)
During handling of the above exception ('NoneType' object has no attribute 'get_div_goalsint_wdays'), another exception occurred:
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in _resolve_lookup
896. current = current[int(bit)]
During handling of the above exception (invalid literal for int() with base 10: 'get_div_goalsint_wdays'), another exception occurred:
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\core\handlers\exception.py" in inner
41. response = get_response(request)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\core\handlers\base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\core\handlers\base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\DevProj\am\amreports\reports\views.py" in goals_view
61. 'int_monthtodate': int_monthtodate_goals,
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\shortcuts.py" in render
30. content = loader.render_to_string(template_name, context, request, using=using)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\loader.py" in render_to_string
68. return template.render(context, request)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\backends\django.py" in render
66. return self.template.render(context)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in render
207. return self._render(context)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in _render
199. return self.nodelist.render(context)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in render
990. bit = node.render_annotated(context)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in render_annotated
957. return self.render(context)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\loader_tags.py" in render
177. return compiled_parent._render(context)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in _render
199. return self.nodelist.render(context)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in render
990. bit = node.render_annotated(context)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in render_annotated
957. return self.render(context)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\loader_tags.py" in render
72. result = block.nodelist.render(context)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in render
990. bit = node.render_annotated(context)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in render_annotated
957. return self.render(context)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in render
1040. output = self.filter_expression.resolve(context)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in resolve
730. arg_vals.append(arg.resolve(context))
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in resolve
849. value = self._resolve_lookup(context)
File "C:\pycharm-virtenv\DjangoPostgres\lib\site-packages\django\template\base.py" in _resolve_lookup
903. (bit, current)) # missing attribute
Exception Type: VariableDoesNotExist at /reports/goals/
Exception Value: Failed lookup for key [get_div_goalsint_wdays] in 'None'
I tried this filter:
<tr>
<td>Interest</td>
<td class="data">${{int_numbers.get_sum_int_daily_numbers | intcomma }}</td>
<td class="data">${{int_goals.get_div_goalsint_wdays | intcomma }}</td>
<td class="data"><font class="red">
{% if int_numbers.get_sum_int_daily_numbers|sub:int_goals.get_div_goalsint_wdays is "None" %}
0
{% else %}
${{ int_numbers.get_sum_int_daily_numbers|sub:int_goals.get_div_goalsint_wdays | intcomma }}
{% endif %}
</font>
</td>
</tr>
Received the same error.
Is there a way with template tags and filters to correct this issue?
Seems that "int_goals" is undefined, thus None. If you try to do a math operation on
int_numbers.get_sum_int_daily_numbers - None.get_div_goalsint_wdays python will throw an exception

Sending multiple instance forms to template - Django

Hi Stack overflow people:
I would lithe to receive some orientation in this following newbie python Error
I have two model forms in my forms.py:
class StrategicDnaValuePropositionForm(forms.ModelForm):
title = "Adn Estratégico y Propuesta de valor"
class Meta:
widgets = {
'familiar_enterprise':forms.RadioSelect,
'enterprise_concepts':forms.RadioSelect,
'value_purpose_target':forms.RadioSelect,
'competition_differentiation':forms.RadioSelect,
'goals_objectives':forms.RadioSelect,
'avoid_competition':forms.RadioSelect,
'enterprise_strategy':forms.RadioSelect,
}
model = StrategicDnaValueProposition
fields = ('familiar_enterprise', 'enterprise_size',
'enterprise_concepts', 'value_purpose_target', 'competition_differentiation', 'goals_objectives',
'avoid_competition')
class MarketingSalesForm(forms.ModelForm):
title = "Mercadeo y Ventas"
class Meta:
widgets = {
'key_activities':forms.RadioSelect,
'new_clients_strategies':forms.RadioSelect,
}
model = MarketingSales
fields = ('key_activities', 'new_clients_strategies',)
In my view, I would like to generate two forms instances of these model forms and send to the template to save them.
My views.py:
#login_required
def diagnostic_tool_questions(request):
user = request.user
# Populate the forms
form_diagnostic = []
if user.is_enterprise:
profile = user.get_enterprise_profile()
form_diagnostic.append({
'form_strategicdna': StrategicDnaValuePropositionForm,
'form_marketing_sales': MarketingSalesForm,
'instance': user.enterpriseprofile,
})
if request.method == 'POST':
# forms = [x['form'](data=request.POST,) for x in form_diagnostic]
forms = [x['form'](data=request.POST, instance=x['instance'],) for x in form_diagnostic]
if all([form.is_valid() for form in forms]):
for form in forms:
form.save()
return redirect('dashboard')
else:
forms = [x['form'](instance=x['instance']) for x in form_diagnostic]
return render(
request, 'enterprise_process/strategicdnavalueproposition_form.html',
{'forms':forms, 'userprofile':profile,})
My template is:
{% extends 'layout.html' %}
{% load bootstrap3 %}
{% block title_tag %}Herramienta de Diagnóstico | CRIMBLU {{ block.super }}{% endblock %}
{% block body_content %}
<div class="container">
<h1>Account Details</h1>
<form method="POST">
{% csrf_token %}
{% for form in forms %}
{% bootstrap_form form %}
{% endfor %}
<input type="submit" value="Save Changes" class="btn btn-default">
</form>
</div>
{% endblock %}
When I go to the url which call to my diagnostic_tool_questions view I get the following message:
System check identified no issues (0 silenced).
May 26, 2017 - 19:40:20
Django version 1.11, using settings 'consultancy.settings.development'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Internal Server Error: /herramienta-diagnostico/preguntas/
Traceback (most recent call last):
File "/home/bgarcial/.virtualenvs/consultancy_dev/lib/python3.5/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/home/bgarcial/.virtualenvs/consultancy_dev/lib/python3.5/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/bgarcial/.virtualenvs/consultancy_dev/lib/python3.5/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/bgarcial/.virtualenvs/consultancy_dev/lib/python3.5/site-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/home/bgarcial/workspace/consultancy_project/enterprise_process/views.py", line 66, in diagnostic_tool_questions
forms = [x['form'](instance=x['instance']) for x in form_diagnostic]
File "/home/bgarcial/workspace/consultancy_project/enterprise_process/views.py", line 66, in <listcomp>
forms = [x['form'](instance=x['instance']) for x in form_diagnostic]
KeyError: 'form'
[26/May/2017 19:40:23] "GET /herramienta-diagnostico/preguntas/ HTTP/1.1" 500 89072
Django tell me that I have some interprete error in the line:
else:
forms = [x['form'](instance=x['instance']) for x in form_diagnostic]
The KeyError: 'form' I unknown the reason which appear ...
Excuse me by the newbie error.

Resources