Django SQLAlchemy engine issue - data not transferred to db using Pandas - html

My use case is to take excel data and load it to database.. I am using SQLAlchemy (with Pandas df) to do that, but am not able to do.. When I try with ORM bulk_create, it works, suggesting to me that Django side of stuff (eg template, url, view, model connections) is working fine, and there could be some issue in defining the Alchemy engine??
I need help from you to debug and resolve this.. My code details are as below.. Please note I dont get any errors in vscode terminal, its just that when I click on Add/ replace button, the data does not transfer.. Appreciate your help.. many thanks..
SQLAlchemy engine details (saved in engine.py)
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from django.conf import settings
engine = create_engine('postgresql://' +
settings.DATABASES['default']['USER'] + ':' +
settings.DATABASES['default']['PASSWORD'] + '#' +
settings.DATABASES['default']['HOST'] + ':' +
str(settings.DATABASES['default']['PORT']) + '/' +
settings.DATABASES['default']['NAME'])
Session = sessionmaker(bind=engine)
session = Session()
views.py
from .models import Industry
from .engine import engine, session
import pandas as pd
def industry_import_replace(request):
df = pd.read_excel('Industry.xlsx')
df.to_sql('Industry', engine, if_exists='replace', index=False)
return render(request, 'portfolio/partials/imports/industry-import.html',{})
template (html)
<form method="post">
<div class="row">
<div class="col col-md-4 col-lg-4">
<table class="table">
<thead>
<tr>
<th scope="col-md-4 col-lg-4">Imports</th>
<th scope="col-md-4 col-lg-4"> </th>
<th scope="col-md-4 col-lg-4"> </th>
</tr>
</thead>
<tbody>
<tr>
<th scope="col-md-4 col-lg-4">Industry</th>
<td>
<button type="submit" name="action" value="replace" class="btn btn-danger"
hx-post="{% url 'portfolio:industry-import-replace' %}" hx-target="#imports">Add/ Replace</button>
</td>
<td>
<button type="submit" name="action" value="append" class="btn btn-success"
hx-post="{% url 'portfolio:industry-import-append' %}" hx-target="#imports">Append</button>
</td>
</tr>
</tbody>
<div id="imports"></div>
</div>
excel file data
Stored right at the top; no row headers etc..
ID industry_name
Ind1
Ind2
Ind3
Industry model file
class Industry(models.Model):
industry_name = models.CharField(max_length=100, unique=True)
class Meta:
verbose_name_plural = 'Industry'
def __str__(self):
return self.industry_name

Related

Django: How to display specific object to specific user

I am new to django and working on a project where admin have to assign a team to manager and when ever admin assign a team to manager then it will be shown to that specific manager only.I have no idea how can i do this. Please if someone can help please help me.
here is my .html file for admin from where admin can assign team to manager.
<thead>
<tr>
<th>S No.</th>
<th>COMPANY NAME</th>
<th>TEAM MEMBER</th>
<th>EMAIL</th>
<th>ASSIGN TEAM</th>
</tr>
</thead>
<tbody>
{%for team in object%}
<tr>
<form id="form_id" method="POST" action = "{% url 'accept' %}">
{% csrf_token %}
<th scope="row"> {{ forloop.counter }}</th>
<td>{{team.company_name}}</td>
<td>{{team.team_member}}</td>
<td>{{team.email}}</td>
<td>
<select name="manager_{{manager.id}}">
{% for manager in managers %}
<option value ="{{manager.id}}">{{manager.name}}</option>
{% endfor %}
</select>
</td>
<td>
<input class="btn btn-raised btn-primary btn-round waves-effect" type="submit" value="Assign">
</td>
</tr>
{% endfor %}
here is my model for the team and manager:
class Create_Team(models.Model):
first_name = models.CharField(max_length= 50)
last_name = models.CharField(max_length= 50)
company_name = models.CharField(max_length= 100)
address = models.CharField(max_length= 1000)
state = models.CharField(max_length= 100)
city = models.CharField(max_length= 100)
status = models.CharField(max_length= 30)
class manager(models.Model):
name = models.CharField(max_length= 500)
designation = models.CharField(max_length= 500)
here is my views.py file for manager and from where the admin is accepting the request:
def accept(request):
obj= Create_Team.objects.filter(status='Accept')
managers = manager.objects.all()
if request.method == 'POST':
acc = manager()
manager_id = int(request.POST.get('manager', 1))
acc.manager = manager.objects.get(pk=manager_id)
return render(request, "admin/accept.html", {"object": obj, "managers": managers})
def superior(request):
return render(request, 'manager/index-3.html')
I want that whenever the admin will click on the assign button then that team will be displayed to that manager.Please help me.
There are several issues with your code.
There is no relation from the Create_Team to the manager model.
The name attribute on your <select> tags do not match the key you using to read from request.POST. manager_{{manager.id}} renders as manager_, so int(request.POST.get('manager', 1)) will always return 1.
The forms in your template do not contain the information which team you want to update.
You do not set the attribute selected on any <option>. As a consequence, the first choice will always be selected.
You are not updating any team in your view.
Let's address these issues.
1 - We fix the models by adding a ForeignKey from CreateTeam to Manager. Note that I've renamed the models, which is optional. If you decide to keep your names, adapt it accordingly.
# models.py
from django.db import models
class CreateTeam(models.Model):
first_name = models.CharField(max_length= 50)
last_name = models.CharField(max_length= 50)
company_name = models.CharField(max_length= 100)
address = models.CharField(max_length= 1000)
state = models.CharField(max_length= 100)
city = models.CharField(max_length= 100)
status = models.CharField(max_length= 30)
manager = models.ForeignKey('Manager', on_delete=models.SET_NULL, null=True, blank=True)
class Manager(models.Model):
name = models.CharField(max_length= 500)
designation = models.CharField(max_length= 500)
You have to pass two bits of information to the assign view: the id of the CreateTeam you want to assign and the id of the Manager you want to assign it to.
Note that the name attribute of form fields is the key in request.POST. These can be any string, just make sure it matches between form and view. It obviously makes life to give them an expressive name.
2 - Sending the id of the Manager is handled by the <select>. Just make sure the name attribute matching the key you use in your view.
3 - To send the id of the team, you could use a <button type="submit"> with a name and a value instead of the <input type="submit">.
<button class="btn btn-raised btn-primary btn-round waves-effect" type="submit" name="team" value="{{ team.id }}">Assign</button>
</td>
Alternatively, you could use a hidden field.
4 - Finally, you have to have to set the attribute selected on the correct <option> in your <select>. You can do that like this:
<option value="{{manager.id}}" {% if team.manager.id == manager.id %}selected{% endif %}
Here is the complete template:
<html>
<head></head>
<body>
<table>
<thead>
<tr>
<th>S No.</th>
<th>COMPANY NAME</th>
<th>TEAM MEMBER</th>
<th>EMAIL</th>
<th>ASSIGN TEAM</th>
</tr>
</thead>
<tbody>
{%for team in teams%}
<tr>
<form id="form_id" method="POST" action="{% url 'accept' %}">
{% csrf_token %}
<th scope="row"> {{ forloop.counter }}</th>
<td>{{team.company_name}}</td>
<td>{{team.team_member}}</td>
<td>{{team.email}}</td>
<td>
<select name="manager">
{% for manager in managers %}
<option value="{{manager.id}}" {% if team.manager.id == manager.id %}selected{% endif %}>{{manager.name}}</option>
{% endfor %}
</select>
</td>
<td>
<button class="btn btn-raised btn-primary btn-round waves-effect" type="submit" name="team" value="{{ team.id }}">Assign</button>
</td>
</form>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
5 - When receiving a POST request, you can assign the manager to the team.
That means you have to use the id values to get a CreateTeam instance and a Manager instance. Then you assign the Manager to createteam.manager and save the createteam object.
from django.shortcuts import get_object_or_404, redirect, render
from .models import CreateTeam, Manager
def accept(request):
teams = CreateTeam.objects.filter(status='Accept')
managers = Manager.objects.all()
if request.method == 'POST':
createteam_id = int(request.POST.get('team', 1))
manager_id = int(request.POST.get('manager', 1))
createteam = get_object_or_404(teams, pk=createteam_id)
createteam.manager = get_object_or_404(Manager, pk=manager_id)
createteam.save()
redirect('accept')
return render(request, "admin/accept.html", {"teams": teams, "managers": managers})
There are three things worth highlighting:
We use get_object_or_404 instead of Model.objects.get. As the name implies, it returns a 404 if no model can be found. This serves as a simple error handling for edge cases like a user manipulating the form or a manager being deleted while the user has the page open. This error handling could be improved to be more user-friendly, but it's a start.
get_object_or_404 can take a model or a queryset. We load the team instance from the filtered queryset teams. Otherwise, a user could manipulate a form and assign a manager to a team that has a status other than Accept.
After saving the team, we redirect to the accept page. This is good practice and ensures that a user can reload the page without seeing the do you want to resubmit this form dialog.
Finally, make sure that this view is really only accessible by the admin, e.g. by adding an appropriate user_passes_test decorator.

Linking button to new page in Django not working

I have created an update view and am trying to link it to my form
but the button linking doesn't seem to be working at all
urls.py
path('uploadupdate/<int:upload_id>', UploadUpdate.as_view(), name='uploadupdate'),
template:
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>Manage uploads</title>
<link rel="stylesheet" href="{% static 'studyadmin/manageuploads_css.css' %}">
</head>
<body>
<table >
<tr class="main_row">
<th> Upload Name </th>
<th> Author Name </th>
<th> Type </th>
<th> Date </th>
<th> Edit </th>
<th>Edit Tags</th>
</tr>
<form >
{% csrf_token %}
{% for uploads in uploads %} <!-- shows all contents -->
<tr>
<th> {{ uploads.title}} </th>
<th> {{ uploads.author }} </th>
<th> {{ uploads.upload_type }} </th>
<th> {{ uploads.date_posted|date:"d M, Y" }} </th>
<th> <button href="{% url 'uploadupdate' uploads.upload_id %}" type="submit" class="edit" formmethod="POST">Edit</button> </th>
<th> <button href="#" type="submit" class="edittags" formmethod="POST" >Edit tags</button> </th>
{% endfor %}
</form>
</table>
</body>
</html>
views.py
class UploadUpdate(UpdateView):
form_class = UploadEditForm
template_name = 'studyadmin/upload_update_form.html'
queryset = Uploads.objects.all()
def get_object(self, queryset=None):
obj = Uploads.objects.get(upload_id=self.kwargs['upload_id'])
print(obj)
return obj
def form_valid(self, form):
upload = form.save(commit=False)
upload.save()
return redirect('/manageupload/')
I added the relevant code, I feel like its a small error but I can't seem to identify it since I'm very new to Django, any help would be appreciated!
You should refer to your app to use that URL because Django doesn't know to which app your URL name belongs to by default. So it'd be something like <button href="{% url 'appname:uploadupdate' uploads.upload_id %}" type="submit" class="edit" formmethod="POST">Edit</button>. Of course make sure that your project's URL Configuration includes your app's URLs. Hope it helps.
UPDATE
From the Django Documentation:
...
class ContactView(FormView):
template_name = 'contact.html'
form_class = ContactForm
success_url = '/thanks/'
def form_valid(self, form):
form.send_email()
return super().form_valid(form)
Notes:
FormView inherits TemplateResponseMixin so template_name can be used here.
The default implementation for form_valid() simply redirects to the success_url.
So you should edit your View.
dont do this in your forms , Use it for getting the Fields from the models and the view allows you to connect your forms directly with your page you can directly print our data in a page so there is an example :
My models i have Question and ansewer attribute :
------ models.py ------
class Question_cours(models.Model):
quest = models.CharField(max_length= 200 ) ---> question
rep = models.CharField(max_length = 20) ----> answer
--------- forms.py --------
class Form_question(forms.Form): /// important to make the same name fields
quest = forms.CharField()
rep = forms.CharField()
-------- view.py ----------
#-----------------------------------------------------------------------------
def add_question_cours(request):
form = Form_question()
if request.method == "POST":
form = Form_question(request.POST)
if form.is_valid() :
Question_cours.objects.create(**form.cleaned_data)
else :
print(form.errors)
return render(request , 'bootstrap/add_question.html',context)
#------------------------------------------------------------------------------
-----------urls.py------------
path('dfsdf',views.add_question_cours,name='add_question')
-----------------add_question.html----------
<form method="POST">{% csrf_token %}
<div class ="form-group">
{{ form.as_p}}
</div>
<button type =" submit" class="btn btn-danger ">
<i class ="fa fa-plus"></i>
</button>
for more information
https://youtu.be/uz5gyXemak0

How return json in django for bootstrap table

How return json from queryset - A.objects.all() to bootstrap table (http://wenzhixin.net.cn/p/bootstrap-table/docs/examples.html):
<table data-toggle="table" data-url="data" data-cache="false" data-height="299">
<thead>
<tr>
<th data-field="id">Item ID</th>
<th data-field="name">Name</th>
</tr>
</thead>
</table>
in views:
data = serializers.serialize("json", A.objects.all())
return render(request, 'a.html', {'data': data})
There is 2 modes : server or client
For server mode:
in utils.py :
from django.core.serializers import serialize
import json
def serialize_bootstraptable(queryset):
json_data = serialize('json', queryset)
json_final = {"total": queryset.count(), "rows": []}
data = json.loads(json_data)
for item in data:
del item["model"]
item["fields"].update({"id": item["pk"]})
item = item["fields"]
json_final['rows'].append(item)
return json_final
in views.py :
from django.http import JsonResponse
json_send = serialize_bootstraptable(Model.objects.all())
return JsonResponse(json_send, safe=False)
You can use Django JsonResponse.
See the documentation here.
You would do something like this:
def my_json_view(request):
context = {'foo': bar}
return JsonResponse(context)
See also this SO question here.
Hope this helps ! :)
Solution:
In views:
def test(request):
data = A.objects.all().values()
return render(request, 'test.html', {'data': data})
In template:
<script type="text/javascript">
$(document).ready(function(){
$('#table').bootstrapTable({
data:{{data|safe}}
});
});
</script>
<table id="table">
<thead>
<tr>
<th data-field="id">Item ID</th>
<th data-field="name">Name</th>
</tr>
</thead>
</table>

cant get ndb query results

i just started learning python ndb i want to know how can i display students attending a selected course (filtering Attendance) then mark their attendance with a ardio button for each student,add the attendance value to the preveious one and finally save the result back to the datastore or print it to file
# -- coding: cp1256 --
import webapp2
import os
import cgi
from google.appengine.ext import ndb
from google.appengine.api import users
from google.appengine.api import mail
from google.appengine.ext.webapp import template
class Student(ndb.Model):
id = ndb.IntegerProperty()
name = ndb.StringProperty()
email = ndb.StringProperty()
#courses= ndb.StructuredProperty(Courses, repeated=True) and attendance
class Course(ndb.Model):
code=ndb.StringProperty()
title=ndb.StringProperty()
#time=ndb.TimeProperity
#students= ndb.StructuredProperty(Students, repeated=True)
#attendance
class Attendance(ndb.Model):
courseCode=ndb.StructuredProperty(Course)
#course=ndb.StructuredProperty(Course, repeated=True)
date=ndb.StringProperty()
#studentID=ndb.IntegerProperty(repeated=True)
student=ndb.StructuredProperty(Student, repeated=True)
attendance=ndb.IntegerProperty(repeated=True)# for each student
class MainHandler(webapp2.RequestHandler):
def get(self):
#cerate ndb from file
coursesfile = open('courses.txt', 'r').read()
studentsfile = open('students.txt', 'r').read()
dailyattendancefile = open('dailyattendance.txt','r').read()
for line in coursesfile.split('\n'):
line=coursesfile.split('\t')
#stroe courses to datastore
course=Course(code=line[0],title=line[1])#create Course entity
course.put()
for line in studentsfile.split('\n'):
line=studentsfile.split('\t')
student=Student(id=int(line[0]),name=line[1],email=line[2])
student.put()
for line in dailyattendancefile.split('\n'):
line=dailyattendancefile.split('\t')
attendance=Attendance(courseCode=Course(code=line[0]),date=line[1],student=Student(id=int(line[2])),attendance=int(line[3]))
attendance.put()
#print to html to test
#self.response.out.write("<tr><td>"+ course.code + "</td>")
#self.response.out.write("<td>"+ course.title+ "</td>")
#self.response.out.write("</tr>")
self.response.out.write("""
<html>
<body>
<form method="post" align="left">
<select align="center" name="course_code">
<option value="cs681" selected>CS681</option>
<option value="cs681">CS611</option>
</select>
<input type="submit" value="Submit"/>
""")
def post(self):
#get info from user
coursecode=self.request.get('course_code')
#self.response.out.write(Attendance.courseCode.code)
self.response.out.write("""
<table align="center" >
<tr align="center">
<td>Course code</td>
<td>Student ID</td>
<td>Date</td>
<td>Attendance</td>
</tr>
""")
qry=Attendance.query(Attendance.courseCode.code==coursecode).fetch()
for ent in qry:
self.response.out.write('<tr><td>%s</td></tr>' %ent.courseCode)
self.response.out.write("""
</table>
</form>
</body>
</html>
""")
app = webapp2.WSGIApplication([
('/', MainHandler)
], debug=True)
Try the following. I think you have a minor issue in your schema definition.
class Course(ndb.Model):
code=ndb.StringProperty(indexed=True)
title=ndb.StringProperty()

How can I take input from a text field in a Django page then update a SQL table with the response?

I am working on a site that will be used to clean up inactive Tableau workbooks. Logging into this site will allow my users to see their old workbooks and decide which ones to keep.
This is going to be accomplished by taking some simple text input from an HTML page, K for keep | D for delete.
The response from the user will then be stored as a Python variable that will go into an if then statement. The if then statement will basically update each row in SQL, adding either K or D to a column called "Marked_for_Deletion".
From there, a stored procedure will run, check that column, and delete all things marked with a D.
Is this feasible? If so, how would I go about pulling that input and making sure it gets added to the right column/row? If not, can you offer any suggestions on a substitute method I can use?
Thanks!
Edit: Here is the code for my table.
<table class="blueTable">
<thead>
<tr>
<th>Workbook Name</th>
<th>Deletion Deadline</th>
<th>Keep or Delete?</th>
</tr>
</thead>
<tbody>
{% for book in Workbooks %}
<tr>
<td>{{ book.name }}</td>
<td>{{ book.owner_name }}</td>
<td>
<label class="container" style="margin-bottom: 25px">
<input type="text" placeholder="(Enter K for Keep, D for Delete)">
</label>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<form method="post">
{% csrf_token %}
<button type="submit" name="run_script">Submit</button>
</form>
</body>
</html>
I want to be able to pull the input from the last td tag and store it with the submit button below there.
I'm kind of late, but I hope it helps you out.
urls.py
from django.urls import path
from workbook_app import views
app_name = 'workbook_app'
urlpatterns = [
path('books/', views.BookListView.as_view(), name='books'),
path('keep_or_delete/<int:pk>/', views.KeepOrDeleteView.as_view(), name='keep_or_delete'),
]
models.py
from django.db import models
class Book(models.Model):
name = models.CharField(max_length=250)
owner_name = models.CharField(max_length=250)
marked_for_deletion = models.BooleanField(default=False)
views.py
from django.views.generic import ListView
from workbook_app.models import Book
from django.http import HttpResponse, HttpResponseRedirect
from django.views import View
from django.urls import reverse
class BookListView(ListView):
template_name = 'workbook_app/books.html'
def get_queryset(self):
return Book.objects.all()
class KeepOrDeleteView(View):
def post(self, request, pk):
book = Book.objects.get(pk=pk)
print(book, book.marked_for_deletion, not book.marked_for_deletion)
book.marked_for_deletion = not book.marked_for_deletion
book.save()
url = reverse('workbook_app:books')
return HttpResponseRedirect(url)
books.html
<div class="container">
<h2>Books</h2>
<table class="table">
<tr>
<th>Workbook Name</th>
<th>Deletion Deadline</th>
<th>Keep or Delete?</th>
</tr>
{% for book in object_list %}
<tr>
<td>{{book.name}}</td>
<td>{{book.owner_name}}</td>
<td>
<form action="{% url 'workbook_app:keep_or_delete' pk=book.pk %}" method="POST">
{% csrf_token %}
<button type="submit" class="btn btn-{%if book.marked_for_deletion %}primary{% else%}danger{% endif %}">{%if book.marked_for_deletion %}Keep{% else%}Delete{% endif %}</button>
</form>
</td>
</tr>
{%endfor%}
</table>
P.S. I'm not handling exceptions, messages, etc. You're just gonna have to figure it out yourself or open a new question.