Django editing model instance - python

The Django project that I am working on lists patient details and lets the user edit the details. I have been able to list it out but views.py is not getting linked to the url for updating the list.
views.py:
def update_patient(request, patient_id):
patient = Patient.objects.get(id=patient_id)
if request.method != 'POST':
form = PatientForm(instance=patient)
else:
# POST data submitted; process data.
form = PatientForm(instance=patient, data=request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('patient:patient',
args=[patient.id]))
context = { 'patient': patient, 'form': form}
return render(request, 'patient/update_patient.html', context)
models.py:
class Patient(models.Model):
patientID = models.CharField(max_length=20)
firstName =models.CharField(max_length=20)
lastName = models.CharField(max_length=20)
age = models.IntegerField(max_length=None)
SSN = models.CharField(max_length=15)
address = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
urls.py:
url(r'^patients/(?P<patient_id>\update\d+)/$', views.update_patient, name='update'),
update_patient.html:
{% extends "patient/base.html" %} {% block content %}
<p>{{ patient }}
</p>
<p>Update Patient:</p>
<form action="{% url 'patient:update' patient.id %}" method='post'>
{% csrf_token %} {{ form.as_p }}
<button name='submit'>add entry</button>
</form>
{% endblock content %}

Your URL pattern is wrong, you have \update within capturing group, it shouldn't be, change the pattern to this:
url(r'^patients/(?P<patient_id>\d+)/update/$', views.update_patient, name='update')

Related

(Django) Can't Update Post On My Blog (function based view)

After displaying my posts, I don't manage to Edit any of them.
When I print the instance variable which is in views.py in my terminal, it displays only the title and the author like this title - author, which is the method defined in models.py.
Help please!
Views.py
#login_required(login_url='login_view')
def update_post_view(request, post_id, slug=None):
instance = Article.objects.get(id = post_id)
if request.method == 'POST':
form = UpdatePostForm(request.POST, request.FILES, instance=instance)
if form.is_valid():
form.save()
return redirect('posts_view')
else:
form = UpdatePostForm(instance=instance)
return render(request,'update_post.html', {'form':form})
forms.py
class UpdatePostForm(forms.ModelForm):
class Meta:
model = Article
fields = ('author',)
title = forms.CharField(max_length=255, label='username',
widget= forms.TextInput(attrs= {'placeholder':'Title...', 'class': 'title'}))
body = forms.CharField(max_length=255, label='body', required=True, widget=forms.Textarea(attrs={'placeholder':'Start writing your post...'}))
urls.py
path('update_post/<int:post_id>/<slug:slug>', views.update_post_view, name='update_post_view')
update_post.html
{% extends 'base.html' %}
{% block title %}Update Post{% endblock %}
{% block content %}
<h2>Update Posts...</h2>
<form action="" method="POST">
{% csrf_token %}
<div>
<h3>{{form.title}}</h3>
<small>{{form.author}}</small>
<p>{{form.body}}</p>
</div>
<button class="btn btn-secondary">Update</button>
</form>
{% endblock %}

Form not submitting to the DataBase when using HTMX

I have the following models, and as you can see they are related to each other
class Leads(models.Model):
project_id = models.BigAutoField(primary_key=True, serialize=False)
created_at = models.DateTimeField(auto_now_add=True)
expected_revenue = MoneyField(decimal_places=2,max_digits=14, default_currency='USD')
expected_licenses = models.IntegerField()
country = CountryField(blank_label='(select_country)')
status = models.CharField(choices=[('Open', 'Open'), ('Closed', 'Closed'), ('Canceled', 'Canceled'),
('Idle', 'Idle')
], max_length=10)
estimated_closing_date = models.DateField()
services = models.CharField(choices=[('Illumination Studies', 'Illumination Studies'),
('Training', 'Training'),('Survey Design Consultancy', 'Survey Design Consultancy'),
('Software License', 'Software License'),
('Software Development','Software Development')], max_length=40)
agent = models.ForeignKey(Profile, default='agent',on_delete=models.CASCADE)
company = models.ForeignKey(Company,on_delete=models.CASCADE)
point_of_contact = models.ForeignKey(Client, default='agent',on_delete=models.CASCADE)
updated_at = models.DateTimeField(auto_now=True)
application = models.CharField(choices=[('O&G','O&G'),('Renewables','Renewables'),('Mining','Mining'),
('Other','Other'),('CSS','CSS')],
default='O&G',max_length=20)
sub_category = models.CharField(choices=[('Wind','Wind'),('Geo-Thermal','Geo-Thermal'),('Solar','Solar'),
('Tidal','Tidal')], max_length=20, blank=True)
#property
def age_in_days(self):
today = date.today()
result = self.estimated_closing_date - today
return result.days
def __str__(self):
return f'{self.project_id}'
class LeadEntry(models.Model):
revenue = MoneyField(decimal_places=2,max_digits=14, default_currency='USD',blank=True)
date = models.DateField()
lead_id = models.ForeignKey(Leads,on_delete=models.CASCADE)
id = models.BigAutoField(primary_key=True, serialize=False)
probability = models.DecimalField(max_digits=2, decimal_places=2, default=0, blank=True)
#property
def est_revenue(self):
result = self.revenue * probabiity
return result
Essentially a lead entry is related to the lead, and I'm using HTMX to essentially add data to LeadEntry database using a form.
Form
class LeadEntryForm(forms.ModelForm):
class Meta:
model = LeadEntry
fields = ('lead_id','date','revenue','probability')
widgets = {'date': DateInput()}
I have 2 views, one that will simply pass an HTML with a button for the user to add entries to the database, and another view with the actual form
views
#login_required
def add_to_forecast(request):
id = request.GET.get('project_id')
request.session['lead_id'] = id
return render(request, 'account/lead_forecast.html')
#login_required
def forecast_form(request):
if request.method=='POST':
form = LeadEntryForm(data=request.POST or None)
if form.is_valid():
form.save(commit=False)
messages.success(request,"Successful Submission")
return redirect('add_to_forecast')
lead_id = request.session['lead_id']
data = {'lead_id':lead_id}
context = {
"form":LeadEntryForm(initial=data)
}
return render(request, 'account/lead_entry_forecast.html', context)
Lastly, there are 2 HTML pages, the first one is associated with add_to_forecast and renders a simple page, this is where the HTMX happens and this adds the form from the next HTML page
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% load static %}
{% block title %}Client Information {% endblock %}
{% block content %}
<h1> Add Lead to Sales Forecast </h1>
<p>Click the Button below to add a Payment Date</p>
<button type="button" hx-get="{% url 'lead_entry_forecast' %}" hx-target="#leadform" hx-swap="beforeend" >
Add Lead </button>
<div id="leadform">
<br>
</div>
{% endblock %}
The form that is added by the user as many times they want to do so
{% load crispy_forms_tags %}
{% load static %}
{% block content %}
<div class="container-fluid">
<form method="post" enctype="multipart/form-data" action=".">
{% csrf_token %}
<div class="row justify-content-center">
<div class="col-sm-1">
{{ form.lead_id|as_crispy_field }}
</div>
<div class="col-sm-2">
{{ form.date|as_crispy_field }}
</div>
<div class="col-sm-2">
{{ form.revenue|as_crispy_field }}
</div>
<div class="col-sm-1">
{{ form.probability|as_crispy_field }}
</div>
<div class="col-sm">
<input type="submit" value="Submit" >
</div>
</div>
</form>
</div>
<hr>
{% endblock %}
The problem I have is that after submitting the form, everything seems to be working, obviously, at the moment you can only submit one lead, as I still have to add more logic, but at the moment the form is not sending data to the DB, after some debugging, I was not able to pass the POST, it seems like is just not submitting anything.
Any help will be highly appreciated
Update - 12/4/2021
I have tried to submit data using the form and it actually works, so there is nothing wrong with the form submitted the POST.request, if I go directly to the URL, it works fine, so the form is submitted correctly and the database is updated.
I still don't understand why is not working when the form is rendered by the htmx, so it has something to do with that.
When you are designing an HTMX page, you have to be careful with the post request, so I was processing the form in the wrong view, please see below the views:
#login_required
def add_to_forecast(request):
form = LeadEntryForm(data=request.POST or None)
if request.method == 'POST':
if form.is_valid():
form.save()
return HttpResponse("Success")
else:
return render(request, 'account/lead_entry_forecast.html', {"form": form})
id = request.GET.get('project_id')
request.session['lead_id'] = id
return render(request, 'account/lead_forecast.html')
#login_required
def forecast_form(request):
lead_id = request.session['lead_id']
data = {'lead_id':lead_id}
context = {
"form":LeadEntryForm(initial=data)
}
return render(request, 'account/lead_entry_forecast.html', context)
Now it works as it should

Django - objects.all() shows nothing

I'm trying to get a list of objects in Django from a model.
I just want to get the list of 'dht node' from the request user, but it shows nothing in the html file (as if the list was empty). The user that I'm using has 2 'dht nodes' and they're shown in the django admin.
I don't know what is wrong, because if I use the instruction "member.dht.create(...)" in the views function and a create a new 'dht node' like this, this is shown. Only 'dht nodes' that I enter by form do not show. Can be the form?
Thanks a lot, Here's my code:
Models.py
class Node(models.Model):
name = models.CharField(primary_key=True, null=False, max_length= 50)
description= models.CharField(default=None, null=False, max_length= 250)
topic=models.CharField(default=None, null=False, max_length= 50, unique=True)
def __unicode__(self):
return self.name
class dht(Node):
temp = models.IntegerField(default=None, null=True)
hum = models.IntegerField(default=None, null=True)
class UserProfile(User):
uid = models.CharField(default=None, null=False, max_length= 250)
dht = models.ManyToManyField(dht, blank=True)
def __unicode__(self):
return self.user.username
Views.py -dht list-
#login_required(login_url = '/web/login')
def listDhtSensor(request):
member = request.user.userprofile
list = member.dht.all()
return render(request, 'web/listDhtSensor.html', {'list':list})
Html -listDhtSensor.html-
{% block content %}
{% for dht in list %}
{{ dht.name }}
{{ dht.topic }}
{% endfor %}
{% endblock %}
Forms.py
class newDHTSensorForm(forms.ModelForm):
class Meta:
model = dht
field = ['name',
'description',
'topic',]
labels = {'name': 'Name' ,
'description': 'Description',
'topic': 'Topic',}
exclude = ['temp', 'hum']
Views.py -dht form-
#login_required(login_url = '/web/login')
def newDHTSensor(request):
if request.method == "POST":
form = newDHTSensorForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.save()
return redirect('/web/dhtDetail')
else:
form = newDHTSensorForm()
return render(request, 'web/newDhtSensor.html', {'form': form})
Html -newDhtSensor.html-
{% block content %}
<div class="boxReg">
<form method="post">
{% csrf_token %}
<h2>{{ form.name.errors.as_text }}</h2>
<p><label for="id_name">Name:</label> <input class="barraForm" type="text" name="name" maxlength="150" autofocus="" required="" id="id_name"></p>
<p><label for="id_description">Description:</label> <input class="barraForm" type="text" name="description" maxlength="150" id="id_description"></p>
<h2>{{ form.topic.errors.as_text }}</h2>
<p><label for="id_topic">Topic:</label> <input class="barraForm" type="text" name="topic" maxlength="254" id="id_topic"></p>
<div class="boxButtonReg">
<button class="buttonReg" type="submit">Save</button>
</div>
</form>
</div>
{% endblock %}
It shows nothing because you did not link you dht objects to that UserProfile, so if you later query for the dhts for that UserProfile, evidently the list is empty. You should add it to the dht relation, like:
#login_required(login_url = '/web/login')
def newDHTSensor(request):
if request.method == "POST":
form = newDHTSensorForm(request.POST)
if form.is_valid():
post = form.save()
request.user.userprofile.dht.add(post)
return redirect('/web/dhtDetail')
else:
form = newDHTSensorForm()
return render(request, 'web/newDhtSensor.html', {'form': form})
Note that you first need to save the post, so you should omit the commit=False aprameter.

Comment form in django didn't save the new comments

I've created a new form for comments the articles on a website. When I add the new comment from django admin everything works ok, but when I try to add the new comment directly from detail page nothings happen and I'am redirecting to the page with list of articles.
here are my files
models.py:
class Komentarz(models.Model):
post = models.ForeignKey(Wpisy, related_name="komentarze", verbose_name="Komentarze do artykułu", on_delete=models.CASCADE)
name = models.CharField(max_length=80, verbose_name="Imię")
email = models.EmailField(verbose_name="Email")
content = models.TextField(verbose_name="Treść komentarza")
created_date = models.DateTimeField(verbose_name="Utworzono", auto_now_add=True)
active = models.BooleanField(verbose_name="Aktywny?", default=True)
class Meta:
ordering = ('created_date',)
verbose_name="Komentarz"
verbose_name_plural="Komentarze"
def __str__(self):
return 'Komentarz dodany przez {} dla strony {}'.format(self.name, self.post)
vies.py with the function of details
from django.shortcuts import render, get_object_or_404
from .models import Wpisy, Komentarz
from .forms import KomentarzeForma
....
def detale_bajki(request, slug, ):
detale_bajki = get_object_or_404(Wpisy, slug=slug)
komentarze = detale_bajki.komentarze.filter(active=True)
if request.method == 'POST':
formularz_komentarza = KomentarzeForma(data=request.POST)
if formularz_komentarza.is_valid():
nowy_komentarz = formularz_komentarza.save(commit=False)
nowy_komentarz.detale_bajki = detale_bajki
nowy_komentarz.save()
else:
formularz_komentarza = KomentarzeForma()
return render(request, 'bajki/detale_bajki.html', {'detale_bajki': detale_bajki, 'komentarze': komentarze, 'formularz_komentarza': formularz_komentarza})
forms.py
from .models import Komentarz
from django import forms
class KomentarzeForma(forms.ModelForm):
class Meta:
model = Komentarz
fields = ('name', 'email', 'content')
and detail.html
...
{% with komentarze.count as total_komentarze %}
<h2>
{{ total_komentarze }} komentarz{{ total_komentarze|pluralize:"y" }}
</h2>
{% endwith %}
{% for komentarz in komentarze %}
Komentarz dodany przez <strong>{{komentarz.name}}</strong>
{{komentarz.created_date}}
<p>
{{ komentarz.content|linebreaks }}<br>
{% empty %}
<p>Nie dodano jeszcze żadnych komentarzy</p>
{% endfor %}
{% if nowy_komentarz %}
<h2>Twój komentarz został dodany</h2>
{% else %}
<h2>Dodaj nowy komentarz</h2>
<form action="." method="post">
{{formularz_komentarza.as_p}}
{% csrf_token %}
<p><input type="submit" value="Dodaj komentarz"></p>
</form>
{% endif %}
clas Wpisy in models.py
class Wpisy(models.Model):
title = models.CharField(max_length=400, verbose_name="Tytuł")
slug = models.SlugField(unique=True, max_length=400,verbose_name="Przyjazny adres url")
content = models.TextField()
status_audio = models.BooleanField(default=False, verbose_name="Czy dostępny będzie plik audio?")
audio_file = models.FileField(upload_to='uploads/',verbose_name="Plik audio")
created_date = models.DateTimeField(blank=True, null=True, verbose_name="Data utworzenia")
category = models.ForeignKey(Kategorie, verbose_name="Kategoria", on_delete=models.CASCADE)
class Meta:
verbose_name="Wpis"
verbose_name_plural="Wpisy"
def __str__(self):
return self.title
Your url pattern is
path('bajki/<slug>', views.detale_bajki, name='detale_bajki')
Note that it doesn't have a trailing slash. Your form's action is "."
<form action="." method="post">
That means you are submitting to /bajki/, which is the wrong URL.
You could fix this by adding a trailing slash to the url (which is common in Django URLs)
path('bajki/<slug>/', views.detale_bajki, name='detale_bajki')
Or you could change the form action to "" instead of ".". In the comments it looks like you fixed the issue by changing the form action to {{ detale_bajki.slug }}.
However these changes to the form action are fragile, and could break if you change your URL patterns again. The best approach is to use the {% url %} tag to reverse the correct URL.
<form action="{% url 'detale_bajki' detale_bajki.slug %}" method="post">
Try out:
nowy_komentarz.post = detale_bajki
...
return render(request, 'html page', {'key': 'what you want to return to your context'}) # don't fornget to add some return to your view.

Form posting Django

I can't get my django app to post to the db. I'm trying to pass my foreign key so I can post it correctly.
Sorry if it's something basic I'm missing I'm just starting. I think it never gets to form = ResultForm(request.POST). And just gives me the form = ResultForm.
Here is my code:
Model:
class Result(models.Model):
category = models.ForeignKey(Category)
category_result = models.CharField(max_length=200)
rating = models.DecimalField('', '', 8, 3)
votes = models.IntegerField(default=0)
created_by = models.IntegerField(default=0, null=True, blank=True)
created_on = models.DateTimeField('created on')
def __unicode__(self):
return self.category_result
Form:
class ResultForm(forms.ModelForm):
category_result = forms.CharField(max_length=200,help_text="Your best line")
rating = forms.DecimalField(widget=forms.HiddenInput(), initial=0)
votes = forms.IntegerField(widget=forms.HiddenInput(), initial=0)
created_by = forms.IntegerField(widget=forms.HiddenInput(), initial=1)
category = forms.IntegerField(widget=forms.HiddenInput())
class Meta:
model = Result
fields = ('category_result', 'rating', 'votes')
view:
def help_out(request, category_id):
if request.method == 'POST':
form = ResultForm(request.POST)
if form.is_valid():
form.save(commit=False)
form.category = category_id
form.save()
return index(request)
else:
print form.errors
else:
form = ResultForm
context = {'form': form, 'category_id': category_id}
return render(request,'pocketwingman/help_out.html', context)
template:
<!DOCTYPE html>
<html>
<head>
<title>Pocketwingman</title>
</head>
<body>
<h1>Add a Result</h1>
<form id="result_form" method="post" action="/pocketwingman/help_out/{{category_id}}/">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
{{ field.errors }}
{{ field.help_text}}
{{ field }}
{% endfor %}
<input type="submit" name="submit" value="Create Line" />
</form>
</body>
</html>
url config:
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^(?P<category_id>\d+)/$', views.help_me, name='help_me'),
url(r'^help_out/(?P<category_id>\d+)/$', views.help_out, name='help_out'),
)
You should initiate your form if it's not a POST:
else:
form = ResultForm()
append () to form class.

Categories