On the admin site, I create ConclusionName and RetrospectiveField. I need the fields baseText and comments to appear on the site under the word Application 2 'Retrospective'
Conclusion (app)
models.py
class ConclusionName(models.Model):
name = models.CharField(max_length=250)
def __unicode__(self):
return self.name
class RetrospectiveField(models.Model):
user = models.ForeignKey(User)
conclusionName = models.ForeignKey(ConclusionName)
baseText = models.TextField(max_length=255)
comments = models.TextField(max_length=255)
project = models.ForeignKey(Project)
forms.py
class RetrospectiveFieldForm(forms.Form):
project = forms.ModelChoiceField(queryset=Project.objects.all(), label=u'Project')
conclusionName = forms.ModelChoiceField(queryset=ConclusionName.objects.all(), label=u'ConclusionName')
baseText = forms.TextField(max_length=255, label=u'BaseText')
comments = forms.TextField(max_length=255, label=u'Comments')
class Meta:
model = RetrospectiveField
fields = ('project', 'conclusionName', 'baseText', 'comments',)
views.py
def add_form_retrospective_field(request):
if request.method == 'POST':
form = RetrospectiveFieldForm(request.POST)
if form.is_valid():
retro = RetrospectiveField()
retro.user = User.objects.get(username=request.user)
retro.project = form.cleaned_data.get('project')
retro.conclusionName = form.cleaned_data.get('conclusionName')
retro.baseText = form.cleaned_data.get('baseText')
retro.comments = form.cleaned_data.get('comments')
retro.save()
return redirect('/')
else:
form = RetrospectiveForm()
return render(request, 'completeness/forms_retrospective_field.html', {'form': form})
def showRetrospectiveField(request, slug):
projects = Project.objects.filter(id=slug)
retrospectiveFields = RetrospectiveField.objects.get(project=projects)
return render(request, 'completeness/view_retrospectiveField.html', {'retrospectiveFields': retrospectiveFields})
conclusion/example.html
{% extends 'completeness/base.html' %}
{% load staticfiles %}
{% load i18n %}
{% block title %}{% trans 'Network' %}{% endblock %}
{% block head %}
<meta charset="UTF-8">
<title>Conclusion</title>
<script data-require="jquery#*" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
<link href="style.css" rel="stylesheet" />
<script src="script.js"></script>
{% block js %}
{{ form.media }}
{% endblock %}
{% endblock head %}
{% block content %}
<div class="parent">
<div class="block">
<h3>Application 2 "Retrospective"</h3>
{% for retro in retrospectiveField %}
<p>{{ retro.baseText }}</p>
<p>{{ retro.comments }}</p>
{% endfor %}
</div>
</div>
{% endblock content %}
You are returning retrospectiveFields in your showRetrospectiveField view, but you're using retrospectiveField in your for loop of conclusion/example.html
Related
I have a problem while using Django. I was trying to create a learning_log web application from my book and came across this error: NoReverseMatch at /edit_entry/8/
Reverse for 'topic' with arguments '('',)' not found. 1 pattern(s) tried: ['topics/(?P<topic_id>[0-9]+)/\Z']. It said it was because of this line in my edit_entry.html file: p>{{ topic }}</p> but I checked my entire project and couldn't find the reason,
Here is my urls.py:
from django.urls import path
from . import views
app_name = 'learning_logs'
urlpatterns = [
path('', views.index, name='index'),
path('topics/', views.topics, name='topics'),
path('topics/<int:topic_id>/', views.topic, name='topic'),
path('new_topic/', views.new_topic, name='new_topic'),
path('new_entry/<int:topic_id>/', views.new_entry, name='new_entry'),
path('edit_entry/<int:entry_id>/', views.edit_entry, name='edit_entry'),
]
views.py:
from django.shortcuts import render, redirect
from .models import Topic, Entry
from .forms import TopicForm, EntryForm
def index(request):
"""The home page for Learning Log."""
return render(request, 'learning_logs/index.html')
def topics(request):
"""Show all topics."""
topics = Topic.objects.order_by('date_added')
context = {'topics': topics}
return render(request, 'learning_logs/topics.html', context)
def topic(request, topic_id):
"""Show a single topic and all its entries."""
topic = Topic.objects.get(id=topic_id)
entries = topic.entry_set.order_by('-date_added')
context = {'topic': topic, 'entries':entries}
return render(request, 'learning_logs/topic.html', context)
def new_topic(request):
"""Add a new topic."""
if request.method !='POST':
form = TopicForm()
else:
form = TopicForm(data=request.POST)
if form.is_valid():
form.save()
return redirect('learning_logs:topics')
context = {'topic': topic, 'form': form}
return render(request, 'learning_logs/new_entry.html', context)
def edit_entry(request, entry_id):
"""Edit and existing entry."""
entry = Entry.objects.get(id=entry_id)
topic = entry.topic
if request.method !='POST':
form = EntryForm(instance=entry)
else:
form = EntryForm(instance=entry, data=request.POST)
if form.is_valid():
form.save()
return redirect('learning_logs:topic', topic_id=topic.id)
context = {'entry': entry, 'topic': topic, 'form': form}
return render(request, 'learning_logs/edit_entry.html')
models.py:
from django.db import models
class Topic(models.Model):
"""A topic the user is learning about."""
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
"""Return a string representation of the model."""
return self.text
class Entry(models.Model):
"""Something specific about a learned topic."""
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'entries'
def __str__(self):
"""Return a string representation of the model."""
return f"{self.text[:50]}..."
forms.py:
from django import forms
from .models import Topic, Entry
class TopicForm(forms.ModelForm):
class Meta:
model = Topic
fields = ['text']
labels = {'text': ''}
class EntryForm(forms.ModelForm):
class Meta:
model = Entry
fields = ['text']
labels = {'text': ''}
widgets = {'text': forms.Textarea(attrs={'cols': 80})}
base.html:
<p>
Learning Log
Topics
</p>
{% block content %}{% endblock content %}
topics.html:
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Topics</p>
<ul>
{% for topic in topics %}
<li>
{{ topic }}
</li>
{% empty %}
<li>No topics have been added yet.</li>
{% endfor %}
</ul>
Add a new topic
{% endblock content %}
new_topic.html:
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Add a new topic:</p>
<form action="{% url 'learning_logs:new_topic' %}" method='post'>
{% csrf_token %}
{{ form.as_p }}
<button name="submit">Add topic</button>
</form>
{% endblock content %}
new_entry.html:
{% extends "learning_logs/base.html" %}
{% block content %}
<p>{{ topic }}</p>
<p>Add a new entry:</p>
<form action="{% url 'learning_logs:new_entry' topic.id %}" method='post'>
{% csrf_token %}
{{ form.as_p }}
<button name='submit'>Add entry</button>
</form>
{% endblock content %}
topic.html:
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Topic: {{ topic }}</p>
<p>Entries:</p>
<p>
Add new entry
<ul>
{% for entry in entries %}
<li>
<p>{{ entry.date_added|date:'M d, Y H:i' }}</p>
<p>{{ entry.text|linebreaks }}</p>
<p>
Edit entry
</p>
</li>
{% empty %}
<li>There are no entries for this topic yet.</li>
{% endfor %}
</ul>
{% endblock content %}
edit_entry.html:
{% extends "learning_logs/base.html" %}
{% block content %}
<p>{{ topic }}</p>
<p>Edit entry</p>
<form action="{% url 'learning_logs:edit_entry' entry.id %}" method='post'>
{% csrf_token %}
{{ form.as_p }}
<button name="submit">Save changes</button>
</form>
{% endblock content %}
index.html:
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Learning Log helps you keep track of what you've learned.</p>
{% endblock content %}
and that is literally everything I checked and I can't seem to find the error, please help me find the error and fix it.
In views.py, on the edit_entry function, pass context to the render method.
On the very last line of the edit_entry function, in the views.py file, add the context to the arguments you are passing to the returned render method.
def edit_entry(request, entry_id):
"""Edit and existing entry."""
entry = Entry.objects.get(id=entry_id)
topic = entry.topic
if request.method !='POST':
form = EntryForm(instance=entry)
else:
form = EntryForm(instance=entry, data=request.POST)
if form.is_valid():
form.save()
return redirect('learning_logs:topic', topic_id=topic.id)
context = {'entry': entry, 'topic': topic, 'form': form}
return render(request, 'learning_logs/edit_entry.html')
Correct the last line as follows, by adding context. This is so can you can use the entry, topic, and form that you defined in the context in the html template.
return render(request, 'learning_logs/edit_entry.html', context)
Hej!
I'm having trouble with my django filter.
When I put {{myFilter}} in the template I only get an ObjectNumber and when I put {{myFilter.form}} I get the error:
ValueError at /plants/plants/
too many values to unpack (expected 2)
Does anyone have an idea what's going on?
# views.py
def plants_view(request):
plants = Plant.objects.all()
myFilter = PlantFilter(plants)
context = {"plants": plants, "myFilter": myFilter}
return render(request, 'plants/search_table.html', context)
# filters.py
class PlantFilter(django_filters.FilterSet):
class Meta:
model = Plant
fields = ['name',]
it doesn't matter if I use fields = [ ] or fields = '__all__' .
template.html
{% extends "landing/base.html" %}
{% load static %}
{% load i18n %}
{% load admin_urls %}
{% block page-title %} {%translate "View Plants" %} {% endblock %}
{% block head %}
<link href="{% static 'landing/vendor/tabulator/dist/css/tabulator.min.css' %}" rel="stylesheet">
<link href="{% static 'landing/vendor/tabulator/dist/css/bootstrap/tabulator_bootstrap4.min.css' %}" rel="stylesheet">
{% endblock %}
{% block content %}
<br>
<div class="row">
<div class="col">
<div class="card card-body">
<form method="get">
{{myFilter.form}}
<button class="btn-primary" type="submit">Search</button>
</form>
</div>
</div>
</div>
</br>
# models.py
class Plant(models.Model):
name = models.CharField(
max_length=200
)
def __str__(self):
return f"{self.name}"
def serialize(self):
return {
"Name": self.name
}
Did you follow the documentation on this page ?
views.py
def plants_view(request):
plants = Plant.objects.all()
myFilter = PlantFilter(request.GET, queryset=plants)
context = {"plants": plants, "myFilter": myFilter}
return render(request, 'plants/search_table.html', context)
template.html
<form method="get">
{{ myFilter.form.as_p }}
<button class="btn-primary" type="submit">Search</button>
</form>
I use class-based views in a Django app. UpdateView works fine with the same template, form and model like CreateView. But CreateView has the problem with submitting a form. I press the submit button and nothing happens. When I remove <script src="http://code.jquery.com/jquery-3.6.0.slim.min.js" charset="utf-8"></script> from <head> tag it submits.
But I need this script for rendering SimpleMDEField.
Note creates and saves good in the admin panel.
Also works this on js console:
let form = document.getElementById('add');
form.submit()
models.py
class Note(models.Model):
title = models.CharField(max_length=100, null=False, blank=False)
slug = models.SlugField(max_length=254, editable=False, unique=True)
author = models.ForeignKey(
User, on_delete=models.SET_NULL, null=True, editable=False
)
source = models.URLField(blank=True, default='')
body_raw = SimpleMDEField()
body_html = models.TextField(max_length=40000, default='', blank=True)
views.py
#method_decorator(login_required, name='dispatch')
class NoteCreateView(CreateView):
model = Note
fields = ['title', 'source', 'body_raw']
template_name = 'notes/create.html'
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
urls.py
urlpatterns = [
path('', NoteList.as_view(), name='home'),
path('view/<str:slug>/', NoteDetailView.as_view(), name='note'),
path('add/', NoteCreateView.as_view(), name='add'),
path('update/<str:slug>/', NoteUpdateView.as_view(), name='update'),
path('delete/<str:slug>/', NoteDeleteView.as_view(), name='delete'),
]
create.html
{% extends 'layouts/base.html' %}
{% block title %}Create Note{% endblock %}
{% block extrahead %}
<script src="http://code.jquery.com/jquery-3.6.0.slim.min.js" charset="utf-8"></script>
{{ form.media }}
{% endblock %}
{% block main %}
<form method="post" id="add">{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="send" value="Save Note">
</form>
{% endblock %}
base.html
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}project name{% endblock %}</title>
{% block extrahead %}{% endblock %}
</head>
</body>
<div style="max-width: 1490px; padding-left: 40px; padding-right: 40px;">
{% block main %}{% endblock %}
</div>
</body>
</html>
I noticed an error An invalid form control with name='body_raw' is not focusable in js console. I found a question after googling the problem. And one answer helped.
I added novalidate to the form.
<form method="post" novalidate>
Everything works fine.
I'm trying to get data on_submit from input fields in multiple form fields. But I want to use one submit button from one of the fields. is this even possible?
class Form1(FlaskForm):
entry1 = StringField(('Entry 1'))
class Form2(FlaskForm):
entry2 = StringField(('Entry 2'))
submit = SubmitField(('Register'))
#app.route('/index', methods=['GET', 'POST'])
def index():
form1= Form1()
form2= Form2()
if form2.validate_on_submit():
entry1 = request.form.get('entry1')
entry2= request.form.get('entry2')
flash((entry1))
flash((entry2))
return redirect(url_for('main.index'))
return render_template('index.html', form1=form1, form2=form2)
{% extends "base.html" %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block app_content %}
<div class="row">
<div class="col-md-4">
{{ wtf.quick_form(form1)}}
{{ wtf.quick_form(form2) }}
</div>
</div>
{% endblock %}
You could move the Submit button to a new class that inherits the other forms. From what I understand, validate_on_submit() processes and validates the fields of the called form, which includes any fields of inherited form classes.
class Form1(FlaskForm):
entry1 = StringField(('Entry 1'))
class Form2(FlaskForm):
entry2 = StringField(('Entry 2'))
class FinalForm(Form1, Form2):
submit = SubmitField(('Register'))
Now you only have to refer to the final form in the call and rendering.
#app.route('/', methods=['GET', 'POST'])
def index():
form = FinalForm()
if form.validate_on_submit():
entry1 = request.form.get('entry1')
entry2 = request.form.get('entry2')
flash((entry1))
flash((entry2))
return redirect(url_for('index'))
return render_template('index.html', form=form)
Here were the basic html templates I tested with success, trying to keep with the format you showed.
base.html :
{% extends 'bootstrap/base.html' %}
{% block content %}
<div class="container">
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<div class="alert alert-info" role="alert">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
{% block app_content %}{% endblock %}
</div>
{% endblock %}
index.html :
{% extends "base.html" %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block app_content %}
<div class="row">
<div class="col-md-4">
{{ wtf.quick_form(form) }}
</div>
</div>
{% endblock %}
I am not entirely sure if I understand your problem correctly, but you can use WTForms to build your forms. You'd have to define another class though that holds the both classes with the fields you need to submit.
https://wtforms.readthedocs.io/en/stable/
I'm making site for applications. And have two models: Applications and Guests and they have manytomany connection, because application can have 2 or more guests and 1 guest may be in many applications.
For making applications i use formset_factory with delete option. The problem is - I can't find any good examples with code for manytomanyfield and formset and I can't bound them in template. I can't display the table at all. Here's the code.
p.s. don't pay attention to cyrillic symbols
models
class Guests(models.Model):
unique_number_guest = models.IntegerField(unique=True, primary_key=True, verbose_name='№')
organisation = models.CharField(max_length=100, verbose_name='Организация', null=True)
full_name = models.CharField(max_length=100, verbose_name='ФИО')
position = models.CharField(max_length=100, verbose_name='Должность', blank=True, null=True)
chosen = models.BooleanField(default=False, verbose_name='Выбран')
class Applications(models.Model):
ntc_cabins = (
('2-5', '2-5'),
('2-10', '2-10'),
('2-12', '2-12'),
)
ntc_blocks = (
('ЦОК', 'ЦОК'),
('БМЗ', 'БМЗ')
)
unique_number_app = models.IntegerField(unique=False, null=True)
visit_date = models.DateField(default=date.today()+timedelta(days=1), verbose_name='Дата:')
visit_time = models.TimeField(default='12:00', verbose_name='Время:')
cabin = models.CharField(max_length=5, verbose_name='Кабинет:', choices=ntc_cabins, default='2-12')
block = models.CharField(max_length=10, verbose_name='Корпус:', choices=ntc_blocks, default='ЦОК')
author = models.CharField(max_length=100, verbose_name='Автор:')
guests = models.ManyToManyField(Guests)
views
def ApplicationFormation(request):
form = ApplicationsForm(request.POST)
form.guest_instanses = GuestsFormSet(request.POST)
if request.method == "POST":
if form.is_valid():
applications = Applications()
applications.cabin = form.cleaned_data['cabin']
applications.save()
for person in form.guests_visited:
guest = Guests()
guest.full_name = person['full_name']
guest.organisation = person['organisation']
guest.position = person['position']
guest.save()
applications.guests.add(guest)
return HttpResponse('good job')
print(form.errors)
else:
formset = GuestsFormSet()
print('FORMSET:', formset)
return render(request, 'myprofile/applications_form.html', {'form': form, 'fomset': formset})
forms
class GuestsForm(ModelForm):
organisation = forms.CharField()
full_name = forms.CharField()
position = forms.CharField()
class Meta:
model = Guests
exclude = ('unique_number_guest', 'chosen',)
GuestsFormSet = formset_factory(GuestsForm, extra=1, can_delete=True)
class ApplicationsForm(ModelForm):
visit_date = forms.DateField()
visit_time = forms.TimeField()
cabin = forms.CharField()
block = forms.CharField()
guests = GuestsFormSet()
class Meta:
model = Applications
exclude = ('unique_number_app', 'author', 'guests', 'ntc_cabin')
and template
{% extends "base.html" %}
{% load static %}
{% block title %}{% endblock %}
{% block content %}
<h2>Заявка на пропуск</h2>
<hr>
<div class="col-md-4">
<form action="" method="post" class="">
{% csrf_token %}
{{ form.as_p }}
<h3>Гости</h3>
<table id="table-guests">
{{ formset.management_form }}
{% for form in formset %}
{% if forloop.first %}
<thead>
<tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}</th>
{% endfor %}
</tr>
</thead>
{% endif %}
<tr class="{% cycle row1 row2 %} formset_row">
{% for field in form.visible_fields %}
<td>
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<input type="submit" value="Сохранить и сформировать заявку"/> Назад
</form>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="{% static 'formset/jquery.formset.js' %}"></script>
<script type="text/javascript">
$('.formset_row').formset({
addText: 'добавить',
deleteText: 'удалить',
prefix: 'Guests'
});
</script>