I'am trying to Update existing objects from a database with a form.
What I need to obtain is :
1 displaying the data to be modified, 2, change the data with the new ones 3, display the new one.
I managed step 1 but its a mystery for step 2. Could you give me a hand ?
Here is my code :
Views.py
`def modec(request, etatcivil_id):
if not request.user.is_authenticated():
return render_to_response('cv/connexionrequired.html')
k = request.user.email
if request.method == 'POST':
ec = Etatcivil.objects.get(id=etatcivil_id)
form = EtatCivilForm(data=request.POST, instance=ec)
form.auteur=k
print "Product Post"
if form.has_changed():
print "form has changed"
if form.is_valid():
print "Display Form"
form.save(commit=False)
fom.save()
return HttpResponseRedirect('/cv/creer')
else:
eta = Etatcivil.objects.get(id= etatcivil_id)
form = EtatCivilForm(eta.__dict__)
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('cv/modec.html', args)`
Model.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
from django.conf import settings
class MyUserManager(BaseUserManager):
def create_user(self, email, password=None):
if not email:
raise ValueError('Users must have an email address')
if not username: username = email.split('#')[0]
user = self.model(
email= MyUserManager.normalize_email(email))
user.set_password(password)
user.save(using=cv._db)
class MyUser(AbstractBaseUser):
email = models.EmailField(max_length=254, unique=True, db_index=True)
registration = models.DateField(auto_now_add=True)
objects = MyUserManager()
USERNAME_FIELD = 'email'
class Meta:
unique_together = ('email', )
class Etatcivil(models.Model):
Auteur = models.ForeignKey(settings.AUTH_USER_MODEL, 'email')
Nom = models.CharField(max_length=70)
Prenom = models.CharField(max_length=70)
Date_de_Naissance = models.DateTimeField()
Email = models.CharField(max_length=70)
Telephone = models.CharField(max_length=15)
Reseaux = models.CharField(max_length=30)
and modec.html
<!DOCTYPE html>
{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static 'cv/style/style.css' %}" />
<html style="width: 100%; min-width:50%;">
<head>
<meta charset="utf-8" />
<title> Créer votre CV</title>
</head>
<body>
<header>
<table>
<tr style=" topmargin: 0px; leftmargin: 0px ">
<td style="padding: 0px; topmargin: 0px; leftmargin: 0px; width=70% ">
<img src=" {% static "cv/photos/logo.png" %}"/>
</td>
<td class="menutd">
<a style="color: #404040;" href="/cv/creer"> Enregistrer mes Informations </a>
</td>
<td class="menutd">
{% block content %}
<a style="color: #404040;" href="/cv/generer"> Generer un CV </a>
</td>
<td class="menutd">
<a style="color: #404040;" href="/login/off" align="left"> Deconnection </a>
</td>
</tr>
</table>
</header>
<div style=" width: 50%; Height: 100%; line-height: 100%; margin-top: 150px; margin-bottom: auto; margin-left: auto; margin-right: auto; vertical-align: middle; text-align: center; font-family: Helvetica Neue; font-size: 36px; color: #ffffff">
<form action="" method="POST"> {% csrf_token %}
{% for field in form %}
<input type="{{ field.Charfield }}" name="{{ field.name }}" value="{{ field.value }}"> </input><br />
{% endfor %}
<input type="submit" name="valider mon etat civil" value="Valider Article">
</form>
{% endblock %}
</div>
</div>
</body>
</html>
Where do you think I am wrong ?
Thanks in advance..
EDIT:
It appears that the form is not valid. Any idea ?
I don't know why you think you need to pass the instance's __dict__ attribute to the form when instantiating it. This is the cause of your problem, because the first parameter to a form is the data argument, and passing that makes the form bound - triggering validation, as the documentation explains in great detail.
Instead of doing that, you should do what you have correctly done in the POST block: pass the instance.
eta = Etatcivil.objects.get(id=etatcivil_id)
form = EtatCivilForm(instance=eta)
Also note you are doing some very strange things in the template (what is {{ form.CharField }} supposed to be?) but the one thing you are not doing is showing the form errors, which you should do - otherwise you won't know why the form is not valid. Again, all this is explained in great detail in the documentation.
Related
I am trying to get data and file from the following HTML template:
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File Upload Example</title>
<style>
body {
margin: 0;
}
.center {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
font-size: 16px;
}
</style>
</head>
<body>
<div class="center">
<form method="POST" action="/upload" enctype="multipart/form-data">
<table>
<tr>
<td class="lbl"><label for="sub_id">Subject Id:</label></td>
<td><input class="fld" id="sub_id" type="text" placeholder="01" required></td>
</tr>
<tr>
<td class="lbl"><label for="sub_first_name">First Name:</label></td>
<td><input class="fld" id="sub_first_name" type="text" placeholder="John" required></td>
</tr>
<tr>
<td class="lbl"><label for="sub_last_name">Last Name:</label></td>
<td><input class="fld" id="sub_last_name" type="text" placeholder="Appleceed" required></td>
</tr>
<tr>
<td class="lbl"><label for="files">File upload:</label></td>
<td><input class="fld" name="file" type="file"></td>
</tr>
</table>
<input type="submit" />
<!--<button type='submit' name='selectionsubmit'>Submit</button>//-->
</form>
</div>
</body>
</html>
I am parsing this through flask #app.route:
#app.route("/upload", methods=["GET", "POST"])
def home():
if request.method == "POST":
file = request.files["file"]
data = jsonify(request.form).json()
print(data, flush=True)
when I try to print data, it returns an empty dict. How can I extract the data from HTML with the request, to get, for example, the value of sub_last_name with something like data.form['sub_last_name'] after form submit? Thanks
The content of an input field is accessed via the name attribute of the specific element defined in the HTML template. The reason you only get the data of the file field is that you only defined this attribute for said input field.
To get the data of the other fields, specify an attribute name.
<input type="text" name="sub_last_name" />
You can then query the data as usual and known from the dict type within the endpoint. So you can also ask whether the respective key is included.
sub_last_name = request.form['sub_last_name']
If you are not sure whether the attribute will be passed, you want to specify a default value or convert the type on request, you can also use get. In this case no KeyError is raised, but None or the optional defined default value is returned if the name of the input field is not found.
The default return value is of type str. However, if you also pass the type attribute, the input will be converted as desired. If the type change fails, the default value is returned.
I am new to Django and currently facing a problem to post html tag data into database.
I have a "PICK CASE" button which on click should send the user_id (hidden html tag display:none) and case_id from the HTML Tags and send it to "pick_view" views and from there it should store the data in MySQL database.
For reference please find the image attached. Case view
tables.html
<div class="containers pt-5 pb-3 px-4 py-4">
<input type='hidden' name='csrfmiddlewaretoken' value='{{ csrf_token }}' />
<div class="d-none">
<p>User ID: </p><p class="user-id">{{id}}</p>
</div>
<h3>Case Number:</h3><h2 id="number"></h2>
<h4>Description:</h4>
<p class="mb-5" id="display"></p>
<div class="button d-inline-block" style="max-width: 50%;">
<button type="submit" id="pick" class=" pick-button btn btn-outline-primary border-radius-lg p-3">Pick Case</button>
</div>
<div class="d-inline-block float-lg-end" style="max-width: 50%;">
<button class="btn btn-outline-danger border-radius-lg p-3">Close</button>
</div>
</div>
<script>
$("#pick").click(function(){
var user = $('.user-id').text();
var ca = $('#number').text();
ca = $.trim(ca);
$.ajax({
type:"POST",
url:"{% url 'dashboard:pick_case' %}",
data:{
user_id:user,
case_id:ca,
csrfmiddlewaretoken: '{{ csrf_token }}'
},
success:function(data){
alert(data);
}
});
});
</script>
Views.py
def pick_view(request):
if request.method == 'POST':
case_id = request.POST.get('case_id')
print(case_id)
status = 2
picked = Transaction()
picked.Case_ID = case_id
picked.Status = status
picked.save()
return HttpResponse("Case Picked Successfuly!")
else:
return HttpResponse("POST ERROR")
urls.py
urlpatterns = [
path('dashboard', views.dashboard_view, name='dashboard_view'),
path('tables', views.case_view, name='case_view'),
path('tables', views.pick_view, name='pick_case'),
]
models.py
class Transaction(models.Model): ### Case Progress Table
Case_ID = models.ForeignKey(CaseTable, on_delete=models.CASCADE)
Status = models.ForeignKey(Status, on_delete=models.CASCADE)
Date_Time = models.DateTimeField(default=timezone.now)
After running the below code
success:function(data){
alert(data);
}
I get the following output:
Output for the alert
so apparently, I am not able to pass the values of "user" and "ca" in ajax.
Please Help!!
I am trying to pass lyrics to the html file through flask but it is not formatting properly.
This is how I want it formatted, and I am passing it in the text variable in the same format -
The value of the text variable
This is how it is showing in the html website - The actual result
How do I get it formatted properly on the website as it is already passed in a formatted way.
This is the python code -
import flask
import subprocess
import sys
import generate_unconditional_samples as model
app = flask.Flask(__name__, template_folder='templates')
#app.route('/', methods=['GET', 'POST'])
def main():
if flask.request.method == 'GET':
return(flask.render_template('main.html'))
if flask.request.method == 'POST':
text = model.sample_model("Lyric", None, 0, 1, None, 0.8, 40, 0.0)
print(text)
return flask.render_template('main.html', result = text,)
if __name__ == '__main__':
app.run()
And This is the HTML code -
<!doctype html>
<html>
<style>
form {
margin: auto;
width: 35%;
}
.result {
margin: auto;
width: 100%;
border: 1px solid #ccc;
}
</style>
<head>
<title>Lyric Generator</title>
</head>
<body>
<form action="{{ url_for('main') }}" method="POST">
<fieldset>
<input type="submit">
</fieldset>
</form>
<div class="result" align="center">
{% if result %}
<br> Generated Lyrics:
<p style="font-size:20px">{{ result }}</p>
{% endif %}
</div>
<body>
</html>
I got the answer, just had to use the white-space : pre-line to spilt the lines
.result {
margin: center
width: 100%;
white-space: pre-line;
border: 1px solid #ccc;
}
The Final Result
Not a very experienced user with python here, just picked up python while staying at home. I was looking into integrating the output of flask-table to a website. The following is my python code that creates a simple table for my website.
from flask_table import Table, Col
app = Flask(__name__)
class ItemTable(Table):
name = Col('Name')
description = Col('Description')
Class Item(object):
def __init__(self, name, description):
self.name = name
self.description = description
items = [dict(name='Name1', description='Description1'),
dict(name='Name2', description='Description2'),
dict(name='Name3', description='Description3')]
table = ItemTable(items)
#app.route("/")
def hello():
return render_template('index.html', tStrToLoad=table.__html__())
if __name__ == "__main__":
app.run()
and my html code that takes tStrToLoad from the python code above to display.
<html>
<head>
<title>Test Flask Table</title>
<style>
body
{
background-color: #000000;
color: #FFFFFF;
font-family:Verdana;
font-size:16px;
}
table, th, td
{
border: 1px solid #0088ff;
border-collapse: collapse;
padding: 3px;
font-family:Verdana;
font-size:12px;
text-align: left;
}
</style>
</head>
<body>
a simple test table
<br/><br/>
{{ tStrToLoad }}
</body>
</html>
And instead of showing a table with the data, I have the following output in a black background
a simple test table
<table> <thead><tr><th>Name</th><th>Description</th></tr></thead> <tbody> <tr><td>Name1</td><td>Description1</td></tr> <tr><td>Name2</td><td>Description2</td></tr> <tr><td>Name3</td><td>Description3</td></tr> </tbody> </table>
Upon further investigating, I did a view page source, this is my actual html code that arises from this.
<html>
<head>
<title>Test Flask Table</title>
<style>
body
{
background-color: #000000;
color: #FFFFFF;
font-family:Verdana;
font-size:16px;
}
table, th, td
{
border: 1px solid #0088ff;
border-collapse: collapse;
padding: 3px;
font-family:Verdana;
font-size:12px;
text-align: left;
}
</style>
</head>
<body>
a simple test table
<br/><br/>
<table>
<thead><tr><th>Name</th><th>Description</th></tr></thead>
<tbody>
<tr><td>Name1</td><td>Description1</td></tr>
<tr><td>Name2</td><td>Description2</td></tr>
<tr><td>Name3</td><td>Description3</td></tr>
</tbody>
</table>
</body>
</html>
My question is how do I format it correctly in my python script such that it sends < and > instead of & lt; and & gt;
If you're confident none of the data in the table has un-validated user input then tell Jinja not to escape the html:
{{ tStrToLoad | safe }}
However you may wish to avoid using Flask-tables, and just pass the items list yourself. The template code can become more generic if you also pass some headers in a separate list:
headers = ['Name','Description']
return render_template('index.html',
headers = headers,
objects = items)
Then manually build the table:
{% if objects %}
<table id='result' class='display'>
<thead>
<tr>
{% for header in headers %}
<th>{{header}}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for object in objects %}
<tr>
{% for k, val in object.items() %}
<td>{{val}}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
As you can see, this prevents you from having to hard-code any values into the template.
The syntax of this table is also compatible with datatables, so you if you load the CSS and JS files as per the zero configuration example then your table becomes prettier and can have a builtin search bar and pagination. Let me know if you need further direction on how to do this.
I have the .css which hard codes the place of the search bar. The search bar is using a variable, keywords, called in the forms.py. Lastly the view.py might be another possibility to get the pre-populated text of "Search for a tool" in the search bar.
Which of these codes can I set the value= "Search for a tool", like I do in the HTML editor in the browser?
style.css File probably is the most confusing for me because I can change the initial definitions to [type = "text", value = "Search for a tool"], and then the search bar moves to a new location on the html page and does not have the pre=written text.
...
.search{
width:350px;
margin-left:120px;
float:left;
position:relative;
height:75px;
}
.search input[type="text"], .search input[type='number'], .search input[type="password"] {
margin:20px;
margin-top:25px;
padding: 4px; background:#d8f6fd;
float:right;
border: 1px solid #66c8de;
-moz-box-shadow: 0 1px 1px #ddd inset, 0 1px 0 #fff;
-webkit-box-shadow: 0 1px 1px #ddd inset, 0 1px 0 #fff;
box-shadow: 0 1px 1px #ddd inset, 0 1px 0 #fff;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
}
.search input[type="submit"]{
margin-top:25px;
margin-right:25px;
float:right;
}
...
The forms.py. This uses a char field. I get many errors when I try to add parameters in CharField( blank = False, default = "Enter a tool name")
I am guessing there is nothing that would initialize the search bar with this .py
class Search(forms.Form):
keywords = forms.CharField()
THe views.py Seems like it will only process a request from the search bar, and I would assume that it could initialize.
def search(request):
template = loader.get_template('sharesystem/search.html')
form = Search()
if request.method == 'GET':
form = Search(request.GET)
if form.is_valid():
keywords = form.cleaned_data['keywords']
tools = Tool.objects.filter(name__contains = keywords).values()
if (keywords is ''):
tools = Tool.objects.all()
context = RequestContext(request, {
'tools' : tools, 'form':form })
return HttpResponse(template.render(context))
tools = Tool.objects.all()
context = RequestContext(request, {
'form' : form,'tools' : tools})
return HttpResponse(template.render(context))
To follow up base.html When i add a new line for input, I get mutiple search boxes. When class='search' is called, what do I put in that div?
<div id="headerwrapper">
<div class="centerframe">
<div id="logo">
<a href="{% url 'sharesystem:index' %}" ><img src="{{STATIC_URL}}sharesystem/images/logo.png"border="none" ></a>
</div>
<div class='search' >
<input type="text" name="keywords" placeholder="Enter a tool name"/>
<form action="/sharesystem/search/" method="GET" style='margin-bottom:0;'>
{% csrf_token %}
<input type="submit" value="Search" />
{{ search_form.keywords }}
</form>
</div>
<div style="padding-top:24px;">
<form action="/sharesystem/search/" method="GET" style='margin-bottom:0;'>
{% csrf_token %}
<input type="submit" value="View All Tools" />
</form>
</div>
</div>
</div>
Depending on your business needs, and what browsers you need to support, I'd like to recommend using the HTML input 'placeholder' attribute.
You would need to either override your forms init function and update the widget attrs dictionary from there or explicitly set the widget in your CharField declaration.
keywords = forms.CharField( widget=forms.TextInput(attrs={'placeholder': 'Search for a tool'}))
Use the placeholder attribute of the input HTML tag:
<input type="text" name="keywords" placeholder="Enter a tool name">
You should take a loo into initial data for Forms.
form = Form(initial={'value': 'My Search!'})
In your case:
form = Search()
if request.method == 'GET':
form = Search(request.GET, initial={'value': 'My Search!'})