Getting "|as_crispy_field got passed an invalid or inexistent field" with a field that exists - html

I'm using django-crispy-forms, and have run across an issue where one of my form fields won't render. The error I'm getting is telling me that the form field is either inexistent or invalid, but it definitely exists, and it's pretty much copied from other form fields that work properly on other pages. So I don't really see how it is either of those.
Here's the relevant code:
forms.py
class AddSkillsForm:
all_skills = forms.CharField(
label="Skills ",
widget=forms.HiddenInput(),
required=False
)
view.html
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %}{{ course.name }}{% endblock %}
{% block content %}
{% include 'course/partial/nav.html' with course=course active_breadcrumb=None %}
<div class="card">
<div class="card-header">
{% include 'course/partial/menu.html' with course=course %}
</div>
<div class="card-body">
<dl class="row">
<dt class="col-sm-3">Name:</dt>
<dd class="col-sm-9">{{ course.name }}</dd>
<dt class="col-sm-3">Number of Students:</dt>
<dd class="col-sm-9">{{ total_students }}</dd>
<dt class="col-sm-3">Sections:</dt>
<dd class="col-sm-9">
{% for section in sections %}
<p>{{ section.name }}</p>
{% endfor %}
</dd>
</dl>
</div>
<div class="card-body">
<p>First, you'll need to import any existing students and groups from Canvas</p>
<a class="btn btn-primary" href="{% url 'import_students_and_groups' course.id%}">
Import Students and Groups from Canvas
</a>
<div id="skill_box">
<p>If you would like to use self-reported student skills to form teams, you can define the skills relevant to this course here</p>
<div id="skill_container"></div>
<button type="button" class="btn btn-primary">Add Skill</button>
<form method="post">
{% csrf_token %}
{{ form.all_skills|as_crispy_field }}
<button type="submit" class="btn btn-primary"></button>
</form>
</div>
</div>
</div>
{% endblock %}

In case anyone comes across the same issue, I did find the solution.
In forms.py, each form must take forms.Form as a parameter in order to function properly with django-crispy-forms. I had a different form that I wasn't accessing regularly that also did not do this, so I didn't realize that all the functional forms did. Here's the revised code
forms.py
class AddSkillsForm:
all_skills = forms.CharField(
label="Skills ",
widget=forms.HiddenInput(),
required=False
)

Related

sending data from a "form action" to a views function in django

How are you community, I'm a little confused between my newbies and lack of knowledge, I'm working on a small project in Django and I'm also trying to send data from a form action in the html to another view function but I'm not understanding it well How does this work and on top of that I have to send several data not just one and it confuses me even more, I have the following HTML:
{% extends "base.html" %}
{% block content %}
<main class="container">
<div class="row">
<div class="col-md-10 offset-md-1 mt-5">
<form action="/interface/" method="POST" class="card card-body">
<h1>Interface</h1>
<h4>{{ error }}</h4>
<select name="dv">
<option selected disabled="True">Select Device</option>
{% for device in devicess %}
<option>{{ device.id }} - {{ device.name }}</option>
{% endfor %}
</select>
<br>
{% csrf_token %}
<br>
<button type="submit" class="btn btn-primary">Send</button>
</form>
<br>
{% for interface in interfaces %}
<section class="card card-body">
<h2>{{interface.Interface}}</h2>
{% if interface.Description == "" %}
<p class="text-secondary">none description</p>
{% else %}
<P class="text-secondary">{{interface.Description}}</P>
{% endif %}
<form action= "{% url 'send_description' %}"method="POST">
{% csrf_token %}
<input type="text" name="command" class="form-control" placeholder="Change description">
<br>
<button type="submit" class="btn btn-primary align-content-lg-center">Send change</button>
</form>
<br>
{% if interface.Status == "up" %}
<p class="text-secondary">Interface State: 🟢 Free</p>
{% else %}
<p class="text-secondary">Interface State: 🔴 Used</p>
{% endif %}
</section>
<br>
{% endfor %}
</div>
</div>
</main>
{% endblock %}
and aesthetically to better understand the first POST executed like this:
So far everything is perfect, if I press the "Send change" button it redirects me perfectly, the problem is that I need to send various data such as device.id, interface to that function that I am executing in the action= "{% url 'send_description' %} .Interface and also the content of the input that is inside the same form. Could you give me a hand or a guide on where to find the best way?
regards!
Let me start by saying that this would work way better with JS and AJAX. But, to answer your question, data is passed via Django http request object, in your case, since you have several different forms, it is possible to pass this data by adding a hidden field inside each form with the desired value:
<input type="hidden" name="interface" value="{{ interface.id }}">
And fetch this value form the request object in the view:
interface = request.POST.get('interface')
A full example:
models.py
class Device(models.Model):
name = models.CharField(max_length=100)
class Interface(models.Model):
name = models.CharField(max_length=100)
description = models.CharField(max_length=100, default='interface description field')
status = models.BooleanField(default=False)
device = models.ForeignKey(Device, on_delete=models.CASCADE, related_name='interfaces')
views.py
from django.core.exceptions import ObjectDoesNotExist
def list_interfaces(request):
devices = Device.objects.all()
interfaces = None
try:
selected_device = Device.objects.get(id=request.POST.get('dv'))
interfaces = selected_device.interfaces.all()
except ObjectDoesNotExist:
selected_device = Device.objects.all().first()
if selected_device:
interfaces = selected_device.interfaces.all()
else:
selected_device = None
context = {
'devices': devices,
'selected_device': selected_device,
'interfaces': interfaces
}
return render(request, 'list_device_interfaces.html', context)
def send_description(request):
command = request.POST.get('command')
device = request.POST.get('seleted_device')
interface = request.POST.get('interface')
print(f'command: {command}')
print(f'device_id: {device}')
print(f'device_id: {interface}')
return redirect('core:list-device-interfaces')
urls.py
from core import views
from django.urls import path
app_name = 'core'
urlpatterns = [
path("list/device/interfaces/" , views.list_interfaces, name="list-device-interfaces"),
path("send/description/" , views.send_description, name="send-description"),
]
list_device_interfaces.html
{% extends "base.html" %}
{% block content %}
<main class="container">
<div class="row">
<div class="col-md-10 offset-md-1 mt-5">
<form action="{% url 'core:list-device-interfaces' %}" method="POST" class="card card-body">
{% csrf_token %}
<h1>Device</h1>
<h4>{{ error }}</h4>
<select name="dv">
<option selected disabled="True">Select Device</option>
{% for device in devices %}
<option value="{{ device.id }}" {% if device.id == selected_device.id %} selected {% endif %}>{{ device.id }} - {{ device.name }}</option>
{% endfor %}
</select>
<br>
<br>
<button type="submit" class="btn btn-primary">Send</button>
</form>
<br>
<hr>
<h2>Interfaces</h2>
{% for interface in interfaces %}
<section class="card card-body">
<h2>{{interface.name}}</h2>
{% if interface.description == "" %}
<p class="text-secondary">none description</p>
{% else %}
<P class="text-secondary">{{interface.description}}</P>
{% endif %}
<form action= "{% url 'core:send-description' %}"method="POST">
{% csrf_token %}
<input type="text" name="command" class="form-control" placeholder="Change description">
<input type="hidden" name="seleted_device" value="{{ selected_device.id }}">
<input type="hidden" name="interface" value="{{ interface.id }}">
<br>
<button type="submit" class="btn btn-primary align-content-lg-center">Send change</button>
</form>
<br>
{% if interface.status %}
<p class="text-secondary">Interface State: 🟢 Free</p>
{% else %}
<p class="text-secondary">Interface State: 🔴 Used</p>
{% endif %}
</section>
<br>
{% endfor %}
</div>
</div>
</main>
{% endblock %}

I'm using jinja for this flask app that I'm making and when ever i run it jinja2.exceptions.UndefinedError: 'user' is undefined appears

So, what I am using it for is to render a template that I have.
Here is the code it has a problem with.
`
#views.route('/')
def home():
return render_template("home.html")
`
By the way this is the code in home.html
{% extends "base.html" %} {% block title %}Home{% endblock %} {% block content
%}
<h1 align="center">Notes</h1>
<ul class="list-group list-group-flush" id="notes">
{% for note in user.notes %}
<li class="list-group-item">
{{ note.data }}
<button type="button" class="close" onClick="deleteNote({note,id })"
<span aria-hidden="true">×</span>
</button>
</li>
{% endfor %}
</ul>
<form method="POST">
<textarea name="note" id="note" class="form-control"></textarea>
<br />
<div align="center">
<button type="submit" class="btn btn-primary">Add Note</button>
</div>
</form>
{% endblock %}
I run it. It gives me a link to website. Everything there, No. I run it. It gives me a link to website. And then jinja2.exceptions.UndefinedError: 'user' is undefined is on my website
Check your html file, you may accidently got a variable called user in there

How can I have separate for loops (in separate columns) in a flask template?

The last link in my first for loop in my first column is also the link to the header in my second column where I have a second for loop. In this example the link for Broccoli is also creating a hyperlink in the text Previous Ads and I can't understand why.
There should not be any link in the header Previous Ads. I believe this is an HTML issue in a Flask template so here is my code.
{% extends "layout.html" %}
{% block main %}
<form action="{{ url_for('searched') }}" method="post">
<div class="form-group">
<input placeholder="Search food" type ="search" name="search"/>
<button class="btn btn-success" type="submit" name="action"><span class="glyphicon glyphicon-search"></span></button>
</div>
</form>
<div class="row">
<div class="column">
<h2>Live Ads</h2>
<dl class="desc-info" style ="text-indent: 15%">
{% for ad in ads %}
<a href="{{ url_for('ads', image_key = ad.image_key, posts = ad.image_key)}}">{{ad.title}}
{% endfor %}
</dl>
</div>
<div class="column">
<h2>Previous Ads</h2>
<dl class="desc-info" style ="text-indent: 15%">
{% for inactive_ad in inactive_ads %}
<dt><a href="{{ url_for('ads', image_key = inactive_ad.image_key, posts = inactive_ad.image_key)}}">{{inactive_ad.title}}</dt>
{% endfor %}
</dl>
</div>
</div>
All of the other links are working correctly. desc-info just aligns the text to the left. I have nearly the identical code on another page but the only difference here is that the for loop is in the second column instead of a few rows of href links.
Looks like you've forgotton to close your anchor tags with </a>.
So under 'Live Ads' (think you also forgot the <dt></dt> tags here):
<dt>
{{ad.title}}
</dt>
And under 'Previous Ads':
<dt>
{{inactive_ad.title}}
</dt>

How to use different css for queryset objects?

I have different styles of heading in a 5- column layout newspaper template. I want to apply different css to the title of each column. The queryset is the {% block content %}How can I iterate over the queryset objects and apply different css to each {{ post.title }} variable? Note: html truncated for brevity.
<div class="content">
<div class="columns">
{% block content %}
{% endblock %}
</div>
<div class="column">
<div class="head">
<span class="headline hl1">May the Force be with you</span>
<p><span class="headline hl2">Let go your conscious self and act on instinct</span></p>
</div>
</div>
</div>
i think that {% cicle %} will help you.
{% for o in some_list %}
<div class="{% cycle 'class1' 'class2' 'class3' %}">
...
</div>
{% endfor %}
more about built-in template tags you could read
https://docs.djangoproject.com/en/3.1/ref/templates/builtins/#cycle

Django - Generalising a Template with Optional Sidebar

I have a working solution for a template that allows for optional sidebars. Depending on the options selected by the user; significant DOM manipulations occur.
The working solution is unnecessarily large and features some code duplication. It also doesn't extend nicely.
I'm looking for a far more generic solution. One that allows for easier extending or abstracting so as to not have to repeat myself for every page that features a sidebar.
The Working Solution
{% extends "app/base.html" %}
{% load wagtailcore_tags %}
{% block content %}
{% if self.sidebar == "left" %}
<div class="row">
<div class="4u 12u(mobile)">
{% include "app/includes/sidebar.html" with sidebar_items=self.sidebar_items.all %}
</div>
<div class="8u 12u(mobile) important(mobile)">
<article class="box post">
{% include "app/includes/banner.html" with feed_image=self.feed_image only %}
{{ self.body|richtext }}
{% include "app/includes/related_links.html" with related_links=self.related_links.all only %}
</article>
</div>
</div>
{% elif self.sidebar == "right" %}
<div class="row">
<div class="8u 12u(mobile)">
<article class="box post">
{% include "app/includes/banner.html" with feed_image=self.feed_image only %}
{{ self.body|richtext }}
{% include "app/includes/related_links.html" with related_links=self.related_links.all only %}
</article>
</div>
<div class="4u 12u(mobile)">
{% include "app/includes/sidebar.html" with sidebar_items=self.sidebar_items.all %}
</div>
</div>
{% else %}
<article class="box post">
{% include "app/includes/banner.html" with feed_image=self.feed_image only %}
{{ self.body|richtext }}
{% include "app/includes/related_links.html" with related_links=self.related_links.all only %}
</article>
{% endif %}
{% endblock %}
{% block content %} is first defined here in app/base.html:
<div id="main-wrapper">
<div class="container">
<!-- <article class="box post"> -->
{% block content %}{% endblock %}
<!-- {% include 'app/includes/prev_next.html' %} -->
<!-- </article> -->
</div>
</div>
And sidebar.html looks like this:
{% load wagtailimages_tags %}
{% for sidebar_item in sidebar_items %}
<section class="box">
{% image sidebar_item.image original as img %}
<img src="{{ img.url }}" alt="" />
<header>
<h3>{{ sidebar_item.title }}</h3>
</header>
<p>{{ sidebar_item.body }}</p>
{% if sidebar_item.button_text %}
<footer>
{{ sidebar_item.button_text }}
</footer>
{% endif %}
</section>
{% endfor %}
My initial attempt at generalising it was to try to do all of the conditionals in app/base.html but I faced issues when it came to optionally the location of {{ block content }}.
Any help greatly appreciated.
If the condition to decide type of sidebar are being decided and supplied by the views.py function serving the page, then the best approach would be to simply make different template for each different page.
This solution sounds overly simple, but if correctly modularized(in terms of all the common code being kept in a basefile and being extended as and when needed), this would be the best approach. Even though the number of other templates might increase, it will give shorter load times because of smaller HTML snippets.
In case you do not want the conditional decisions being handled by views.py , you can alternatively use AJAX, and asynchronously change the template being viewed without causing a reload.
Hope this helps!