Django CRUD doesn't reloads the model - python

When I do a crud action to my database it won't change on the website after refreshing the page. I have to restart the server "python manage.py runserver" everytime to see the changes on my website.
I asked another student about this problem and he said he didn't had the problem. I tried to find it on the internet but with no success.
It's add the richting but doesn't show it until I do python manage.py runserver.
richtingen.html (where I add a richting and show the richting)
{% extends 'main_app/base.html' %}
{% load staticfiles %}
{% block main %}
<main>
<div class="messages">
<h2>Richtingen</h2>
<h3>Nieuwe richting maken:</h3>
<form class="all_forms" action="post_richting/" method="POST">
{% csrf_token %}
{{ form.as_p }}
<div>
<button type="submit" name="submit">Verzenden</button>
</div>
</form>
<hr>
<div class="messages">
{% for richting in richtingen %}
<h3 id="{{richting.id}}">{{richting.naam}}</h3>
<p>{{richting.omschrijving}}</p>
Wijzigen
Verwijderen
<hr>
{% endfor %}
</div>
</div>
</main>
{% endblock %}
urls.py
url(r'^[rR]ichtingen/$', views.richtingen, name='richtingen'),
url(r'^richtingen/post_richting/$', views.post_richting, name='post_richting'),
views.py
titel = 'KA Go Malle'
volledigeTitel = 'Koninklijk Atheneum Go Malle'
richtingenObjects = Richtingen.objects.all()
def richtingen(request):
form = RichtingForm()
context = {'titel': titel,
'volledigeTitel': volledigeTitel,
'form': form,
'richtingen': richtingenObjects}
return render(request, 'main_app/richtingen.html', context)
def post_richting(request):
form = RichtingForm(request.POST, request.FILES)
if form.is_valid():
form.save(commit = True)
return HttpResponseRedirect('/richtingen')

You have defined the relevant data outside a function. I'm not sure why you have done this, but that means the query only evaluated once: when the module is first loaded. Don't do this; define the variables inside the function that uses them, so that the query is made ever time.

Related

Content not visible on webpage

I am creating a database website with python and django. My problem is that the content I try to get data from my class' fields doesn't appear on the id-page on django. I am able to make a successful search, and I get links for my searches. The name-field is visible in searches and on the page, but nothing else appears. When I click on the link, I go to luokka_id/number. I must be missing something but can't figure out what the problem is.
models.py
class luokka(models.Model):
nimi = models.CharField('Pääkäyttöluokka', max_length=100)
vara = models.CharField('Varakäyttöluokka', max_length=100)
varaaja = models.CharField('Varakäyttöluokka', max_length=100)
def __str__(self):
return self.nimi
and on the näytä_luokka.html (show class):
{% extends 'tietokanta/base.html' %}
{% block content %}
<center>
{{luokkalistaus}}
{{luokka}}
{{ luokka.nimi }}
{{ luokka.vara }}
{{ luokka.varaaja }}
</center>
{% endblock %}
and views.py:
def näytä_luokka(request, luokka_id):
luokkalistaus = luokka.objects.get(pk=luokka_id)
return render(request, 'tietokanta/näytä_luokat.html',
{'luokkalistaus': luokkalistaus})
I don't get any errors to help me out here. It's just an empty page, but it should show some extra data.
You have named the key of context as luokkalistaus not luokka, so the template should be:
{% extends 'tietokanta/base.html' %}
{% block content %}
<center>
{{ luokkalistaus.nimi }}
{{ luokkalistaus.vara }}
{{ luokkalistaus.varaaja }}
</center>
{% endblock %}

crispy_forms.exceptions.CrispyError: |as_crispy_field got passed an invalid or inexistent field - models.ForeignKey

I'm trying to create a frontend data entry page for an existing model. However, when clicking the link, I get an error:
crispy_forms.exceptions.CrispyError: |as_crispy_field got passed an invalid or inexistent field
Just to be clear, adding the data from Django Admin works with no issues at all.
Having looked through a number of answered questions here, one did highlight what I believe could be problem, but it was out of context and did not provide much of an explanation.
I am trying to create a frontend entry form for users that corresponds with a foreign key.
models.py
class NewHandoff(models.Model):
handoff_pk = models.AutoField(primary_key=True)
handoff_date = models.DateField(auto_now_add=True,verbose_name="Handoff Date")
shift1_pri = models.ForeignKey(Engineer,on_delete=models.CASCADE,verbose_name="Shift 1 Primary")
shift1_sec = models.ForeignKey(Engineer,on_delete=models.CASCADE,verbose_name="Shift 1 Secondary")
def __str__(self):
return f"{self.handoff_date}"
class Meta:
verbose_name_plural = 'Handoffs'
# New Handoff Form
class NewHandoffForm(forms.ModelForm):
class Meta:
model = NewHandoff
fields = ['shift1_pri','shift1_sec']
views.py
from django.shortcuts import redirect, render
from django.views import View
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http.response import HttpResponse
from django.contrib import messages
from .models import AttentionForm, NewHandoffForm
# Handoff View Page
class NewHandoffView(LoginRequiredMixin,View):
def get(self, request):
greeting = {}
greeting['heading'] = "New Handoff"
greeting['pageview'] = "Handoff"
return render (request,'handoff/handoff-new.html')
def post(self, request):
if request.method == "POST":
if "add-new-handoff-button" in request.POST:
create_new_handoff_form = NewHandoffForm(request.POST)
create_new_handoff_form.save()
return redirect("/handoff/handoff-create")
handoff-new.html
{% extends 'partials/base.html' %}
{% load static %}
{% load humanize %}
{% load crispy_forms_tags %}
{% block extra_css %}
<link href="{% static 'libs/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css' %}" rel="stylesheet">
{% endblock %}
{% block contents %}
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<!-- New Form -->
<form method="POST">
{% csrf_token %}
<div class="row">
<div class="row-fluid pb-1">
<!-- Field 1 -->
<div class="mb-3">
{{ form.shift1_pri|as_crispy_field }}
</div>
<!-- End of Field 1 -->
</div>
</div>
<div class="d-flex flex-wrap gap-2">
<button type="submit" class="btn btn-primary waves-effect waves-light" name="add-new-handoff-button">Create New Handoff</button>
</div>
</form>
<!-- End of New Form -->
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_javascript %}
{% endblock %}
Someone mentioned in another post that forms should correlate with the declared form name {{ form.shift1_mod|as_crispy_field }} so it should actually be {{ create_new_handoff_form.shift1_mod|as_crispy_field }} but I have tried changing this and still get the same problem, plus, another model form works fine with just form despite the name of the form being attention_form.
Does anyone have any idea or can point me in the right direction? :)
You are not passing the form through the context in the template. As you are inheriting View, Add the following line in the get() and afterwards in the post() method appropriately:
form = NewHandoffForm()
# and then change return
return render(request,'handoff/handoff-new.html', {'form': form })
Also, you have a space after render in the get function. I hope this is a typo here, but not in your code.

How do you iterate through two items in a model and display on site using Django?

I have a models.py with the following fields:
class ChatStream(models.Model):
bot = models.TextField()
user = models.TextField()
name = models.CharField(max_length=100, null=True)
created_date = models.DateTimeField(auto_now_add=True)
And I'd like on a website to iterate through "bot" and "user" one at a time, so the site would hypothetically display something like:
bot: hello!
user: what's up?
bot: I'm good
user: What's your name
bot: bot is my name
.... etc. this would keep going...
So in my views.py I have
def displayDict(request):
m = ChatStream.objects.all()
return render(request, 'chatStream.html',
{"chat": m})
def send(request):
message = request.POST.get('userMessage', False)
ip = visitor_ip_address(request)
response = routes(message, ip)
print(ip, "user sent:", message, "bot response:", response)
chatItem = ChatStream(bot=response, user=message, name=ip)
chatItem.save()
return HttpResponseRedirect('/chat/')
Then in my template, chat.html I have
{% block chatStream %} {% endblock %}
And chatStream.html (this is where the error is happening I believe... how do you iterate through two items in the model so they appear one after the other on the html file?)
{% extends 'chat.html' %}
{% block chatStream %}
{% for a in bot%}
{% for b in user%}
<p>
<b>bot:</b> {{a}} <br>
<b>user:</b> {{b}} <br>
</p>
{% endfor %}
<form action="/send/" method = "post">{% csrf_token %}
<input type="text" name="userMessage">
<input type="submit" value="Send to smallest_steps bot">
</form>
{% endblock %}
But this does not work -- no text from the model is displayed on the site. I am not understanding how to iterate through two items within the model at once inside of the chatStream.html.
A lot going on here, lets try to break it down:
First, you need to pass context variables to your templates if you want to render them using the (jinja-like) Django template rendering system.
Your view function for rendering the template would look like this:
views.py
def render_chat_page(request):
# do some logic:
...
# pack the context variables:
context = {
'some_key' : 'some_value',
'chat_streams' : ChatStream.objects.all(),
...
}
return render(request, 'chat_page.html', context=context)
Ok, now that we've passed the context variables to the template, we can render html elements using the variables like so:
template.html
<div> The value of "some_key" is: {{some_key}} </div>
{% for chat_stream in chat_streams %}
<div> user says: {{chat_stream.user}}</div>
<div> bot says: {{chat_stream.bot}}</div>
{% endfor %}
This will render the user and bot messages for each ChatStream object. However my hunch is that this is not entirely what you're after, instead you may want something more dynamic.
In your displayDict view you're passing a QuerySet to the context. So, you need to loop over the QuerySet in your template.
{% extends 'chat.html' %}
{% block chatStream %}
{% for item in chat %}
<p>
<b>bot:</b> {{item.bot}} <br>
<b>user:</b> {{item.user}} <br>
</p>
{% endfor %}
<form action="/send/" method = "post">{% csrf_token %}
<input type="text" name="userMessage">
<input type="submit" value="Send to smallest_steps bot">
</form>
{% endblock %}

Django query works in shell, but jinja wont recognize in template

Right now I can run a query in the python shell and have it return True, but when trying to replicate in my html jinja template, I can't get it return the same True result.
I have a query that puts a Post.object.get(id=1) as a variable.
P1=Post.objects.get(id=1)
then ran:
P1.liked_by.all()
which does return results:
<QuerySet [<User: User object(10)>, <User: User object (12), <User: User
object (13)>]>
then I put a variable in for a User found in that query:
JV= User.objects.get(id=10)
This user id is found in the P1.liked_by.all() query, so now when I test to see if it is found.
JV in P1.liked_by.all()
True
Now when I try to access this in my html jinja template. I can not get it to check against it and return true. Even though I can print the values on the page.
Here is my Views.py:
def topic(request,topic_id):
if not 'u_id' in request.session:
return redirect('/')
print(request.session)
context={
"topic":Topic.objects.get(id=topic_id),
"user":User.objects.get(id=request.session["u_id"]),
"posts":Post.objects.filter(topic=topic_id),
}
return render(request, 'topic.html', context)
Here is my HTML:
{% for post in posts %}
<div class="cast-content">
<h3>Casting submit by <u>{{post.user.user_name}}!</u></h3>
<p>number of likes:{{post.liked_by.count}}</p>
<p>post id:{{post.id}}</p>
<p>user_id in session= {{user.id}}</p>
<p>liked by:{{post.liked_by.all}}</p>
<img src="{{post.image.url}}" class="post-pix" alt="...">
<br>
<p>post liked_by values: {{post.liked_by.values}}</p>
{% if user.id in post.liked_by.all %}
Un-Like
{% else %}
<form action="/add-like" method="post">
{% csrf_token %}
<input type="hidden" name="post_id" value="{{post.id}}">
<input type="hidden" name="topic" value="{{topic.id}}">
<input type="submit" value="Like">
</form>
{% endif %}
{% if user.id == post.user.id %}
Remove
{% endif %}
</div>
{% endfor %}
I can not figure out why I can print the values in the template but when I run the {% if %} statement to check if it exists in the table It can't find it therefore defaulting into the {% else %} statement every single time. Any help at all is so greatly appreciated!

Flask WTF – Forms always redirect to root

I have created a simple Flask WTF form
class SequenceForm(Form):
sequence = StringField('Please enter a sequence in FASTA format', validators=[Required()])
submit = SubmitField('Submit')
and I have set up a route to make it appear on a page
#main.route('/bioinformatics')
def bioinformatics():
form = SequenceForm()
return render_template('bioinformatics.html', form=form)
It all works great (so far). When I point my browser to foo/bioinformatics, I see a page with a SequenceForm rendered. However, when I hit the Submit button, I am always taken back to the root page defined by #main.route('/').
How can I make the Submit button take me somewhere else? I would like to use validate_on_submit() and do stuff with the data entered in the form.
Thanks!
/Michael Knudsen
UPDATE (Code from bioinformatics.html)
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Bioinformatics{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Hello, Bioinformatics!</h1>
</div>
{{ wtf.quick_form(form) }}
{% endblock %}
You need to specify an action in the form in your html.
<form action="/url_which_handles_form_data" method="Post">
your code
</form>
make sure to give the correct path if you are using blueprints
Edit:
From https://github.com/mbr/flask-bootstrap/blob/master/flask_bootstrap/templates/bootstrap/wtf.html I found this part.
{% macro quick_form(form,
action="",
method="post",
extra_classes=None,
role="form",
form_type="basic",
horizontal_columns=('lg', 2, 10),
enctype=None,
button_map={},
id="") %}
So you can probably call
{{ wtf.quick_form(form, action="/fancy_url") }}
or
{{ wtf.quick_form(form, action=url_for("blueprint_name.fancy_url")) }}
Depending on where the view is located.
Thanks to Tim Rijavec and Zyber. I used a combination of your suggestions to come up with the following solution.
I added GET and POST to methods for the route
#main.route('/bioinformatics', methods=['GET', 'POST'])
def bioinformatics():
form = SequenceForm()
return render_template('bioinformatics.html', form=form)
and then I wrapped the wtf.quick_form call inside tags.
<form action="{{ url_for('main.bioinformatics') }}" method="POST">
{{ wtf.quick_form(form) }}
</form>
Now everything works beautifully. Thanks!

Categories

Resources