Django - Delete an specific record - python

I need your help please I'm trying to delete an specific record in my table that I already created, I have trying some codes but not working in my django version 1.10.4, Can someone help me?
Here's what I have:
Views.py
from django.shortcuts import render
from django.conf import settings
from .forms import regForm
from .models import registro
from registro.forms import regForm
from django.shortcuts import get_object_or_404
from django.core.urlresolvers import reverse
def test_reg(request):
form = regForm(request.POST or None)
queryset = registro.objects.all()
# query_delete = queryset.delete()
context = {
"form": form,
"queryset": queryset,
}
if form.is_valid():
instance = form.save()
return render(request, "registro.html", context)
def delete(request, id):
note = get_object_or_404(registro, pk=id).delete()
return HttpResponseRedirect(reverse('/'))
Template
<form method="POST" action="">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Registrame" />
</form>
<style>
table, th, td {
border: 1px solid black;
}
</style>
<table>
<tr>
<th>Name</th>
...
<th>Age</th>
...
<th>Delete</th>
</tr>
{% for item in queryset %}
<tr>
...
<td>{{ item.name }}</td>
...
<td>{{ item.age }}</td>
...
<td> Delete </td>
</tr>
{% endfor %}
</table>
urls.py
from django.conf.urls import include, url
from django.contrib import admin
from myselect import views
from registro import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^select/', include('myselect.urls')),
url(r'^delete/(?P<id>\d+)/$',views.delete, name='delete'),
url(r'^$', views.test_reg, name='test_reg')
]
Model.py
from __future__ import unicode_literals
from django.db import models
# Create your models here.
from django import forms
# Create your models here.
class registro(models.Model):
name = models.CharField(max_length=100)
age = models.CharField(max_length=100)
def __unicode__(self):
return self.name
def __str__(self):
return self.name
Basically I have some users in my Database where I'm showing this through a table in my template, I want to delete the first one for example by clicking in my delete option where is in my last cell of my table
I tried this code and I got:
Reverse for 'delete' with arguments '()' and keyword arguments '{u'pk': ''}' not found. 1 pattern(s) tried: ['delete/(?P<id>\\d+)/$']
How can I solve this and make it work good?
Help please... thanks !

The problem is in your template change:
Delete
To:
Delete

Related

Django ListView is missing a QuerySet - Error Message - 2 Models In 1 View

I'm trying to view data from 2 models in a single list view. I'm getting the below error message and I can't seem to figure out why. I have included the browser error, views.py, urls.py and html page. Any assistance would be appreciated and as a side note I'm new to programming, Python and Django.
Error:
ImproperlyConfigured at /scripts/patientsdetails/
PatientListView is missing a QuerySet. Define PatientListView.model, PatientListView.queryset, or override PatientListView.get_queryset().
Request Method: GET
Request URL: http://127.0.0.1:8000/scripts/patientsdetails/
Django Version: 3.2.2
Exception Type: ImproperlyConfigured
Exception Value:
PatientListView is missing a QuerySet. Define PatientListView.model, PatientListView.queryset, or override PatientListView.get_queryset().
urls.py
from django.urls import path
from .views import (
ScriptListView,
ScriptUpdateView,
ScriptDetailView,
ScriptDeleteView,
ScriptCreateView,
PatientListView,
PatientUpdateView,
PatientDetailView,
PatientDeleteView,
PatientCreateView,
)
urlpatterns = [
path('patientsdetails/',
PatientListView.as_view(), name='patient_list'),
]
views.py
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, DeleteView, CreateView
from django.urls import reverse_lazy
from bootstrap_datepicker_plus import DatePickerInput, TimePickerInput
from django.contrib.auth import get_user_model
from django.shortcuts import render
from scripts.models import Patient, Script
from .models import Script, Patient
class PatientListView(LoginRequiredMixin, ListView):
template_name = 'patient_summary.html'
def get_context_data(self, **kwargs):
context = super(PatientListView, self).get_context_data(**kwargs).filter(author=self.request.user)
context['patient'] = Patient.objects.filter(author=self.request.user)
context['script'] = Script.objects.filter(author=self.request.user)
return context
html
{% for patient in object_list %}
<div class="card">
<div class="card-header">
<span class="font-weight-bold">{{ patient.patient_name }}</span> ยท
<span class="text-muted"></span>
</div>
<div class="card-body">
Cycle Start Date - {{ patient.cycle_start_day }} <br>
{% endfor %}
{% for script in object_list %}
Drug Name - {{ script.drug_name }} <br>
{% endfor %}
</div>
<div class="card-footer text-center text-muted">
</div>
</div>
<br />
I think it's clear from the error that you have to define which model/queryset attribute to work upon by list view
Do this in your view:
model = Patient
Or
queryset = Patient.objects.all()
Or override get_queryset method
def get_queryset(self):
return Patient.objects.all()

Display PostgreSQL tables contents in Django

EDIT: Fixed it! in models.py I had to add this to point it to the right table as it uses the folder name as a prefix.
class Meta:
managed = False
db_table = 'tablename'
I'm looking to display the contents of a postgres table in Django. Clearly I'm doing something wrong but can not figure out why the data won't show.
Below is what I have so far, the tables headers show but there is no data or any error messages. Checked the table in pgAdmin and there is plenty of data there.
# models.py
from django.db import models
from datetime import datetime
# Create your models here.
class SensorData(models.Model):
device_name = models.TextField()
sensor_type = models.TextField()
sensor_data = models.SmallIntegerField()
sensor_date = models.DateTimeField()
def __str__(self):
return self.device_name
# views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import ListView
from .models import SensorData
# Create your views here.
class ErrorView(ListView):
model = SensorData
template_name = 'errors.html'
# urls.py
from django.urls import path
from .views import ErrorView
urlpatterns = [
path('errors/', ErrorView.as_view(), name='errors'),
path('', ErrorView.as_view(), name='errors'),
]
# errors.html
{% extends 'layout.html' %}
{%block content %}
<section class ='infoContainer'>
<div id = 'sensorInfo'>
<h2> Error Information </h2>
<table id = "deviceTable">
<tr>
<th><strong>Device </strong></th>
<th><strong>Sensor Type </strong></th>
<th><strong>Date</strong></th>
<th><strong>Information</strong></th>
</tr>
{% for error in object_list %}
<tr>
<td> {{error.device_name}} </td>
<td> {{error.sensor_type}} </td>
<td> {{error.sensor_date}} </td>
<td> {{error.sensor_data}} </td>
</tr>
{% endfor %}
</table>
</div>
</section>
{% endblock content %}

Django button in Modelclass

I'm making an inventory app in which I could update the values of the products from my 'home.html'.
My proj name is Inventory
App name is myapp
Problem I am facing is that every time I update the value of a Stock from my homepage, it adds a new Product instead of updating the one that I want!
I am using the ModelsForm Class provided by Django.
Using Django=1.11 and Python=3.6
My project's urls.py:
from django.conf.urls import url,include
from django.contrib import admin
from myapp.views import home
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^myapp/', include('myapp.urls', namespace="myapp")),
url(r'^myapp/home/', home, name='home'),
]
My forms.py:
from django import forms
from .models import Inventory
class Operations(forms.ModelForm):
class Meta:
model = Inventory
fields = ('stocks_left',)
My app's Model.py:
from django.db import models
import uuid
class Inventory(models.Model):
"""
Model representing a the inventory.
"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
inventory_name = models.CharField("INVENTORY NAME" ,max_length=200, help_text="This contains the Inventory name:")
short_name = models.CharField(max_length=20, help_text="This contains an abbreviation:")
inventory_code = models.IntegerField("INVENTORY CODE" ,default = '0', help_text="This contains the Inventory code:")
price = models.IntegerField(default = '0')
stocks_left = models.IntegerField("STOCKS LEFT",default = '0')
def __str__(self):
"""
String for representing the Model object (in Admin site etc.)
"""
return '{0} ({1}) ({2})'.format(self.inventory_name,self.inventory_code,self.stocks_left)
My app's urls.py
from django.conf.urls import url
from . import views
from django.contrib.auth.views import login
app_name= 'myapp'
urlpatterns = [
url(r'^$', login, {'template_name': 'myapp/login.html'}),
]
and my views.py
from django.shortcuts import render,redirect
from django.contrib import auth
from django.contrib.auth.models import User
from django.views import generic
from django.http import HttpResponse
from myapp.models import Inventory
from .forms import Operations
def home(request):
names = Inventory.objects.all()
if request.method == "POST":
form = Operations(request.POST)
if form.is_valid():
stocks_left = form.save(commit=False)
stocks_left.save()
return redirect('myapp/home.html')
else:
form = Operations()
return render(request, 'myapp/home.html', { "names": names, "form": form})
and my home.html template:
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<title>Inventory</title>
</head>
<body>
<h1>Welcome!</h1>
<div class="container">
<table border="5" cellpadding="10" width="1000">
<thead align="center">
<tr>
<th align="center">#</th>
<th align="center">Name</th>
<th align="center">Inventory Code</th>
<th align="center">Stocks left</th>
<th align="center">Operations</th>
</tr>
<tr>
{% for x in names %}
<td align="center"> {{ x }}</td>
<td align="center"> {{ x.inventory_name }}</td>
<td align="center"> {{ x.inventory_code }}</td>
<td align="center"> {{ x.stocks_left }}</td>
<td><form method="POST">{% csrf_token %}{{form}}<button type="button" class="btn btn-primary"><span class="glyphicon glyphicon-plus"></span></button></form><br></td>
</tr>
{% endfor %}
</table>
</div>
</body>
Here is what you can do,
Create 2 fields in forms,
class Operations(forms.ModelForm):
class Meta:
model = Inventory
fields = ('stocks_left','inventory_name')
When you get the data in the view,
if request.method == "POST":
form = Operations(request.POST)
if form.is_valid():
inv_obj = form.cleaned_data.get('inventory_name')
inv_model_obj = Inventory.objects.get(inventory_name=inv_obj) #make sure to declare in the models that this inventory_name is unique
inv_model_obj.stocks_left = form.cleaned_data.get('stocks_left')
inv_model_obj.save()
return redirect('myapp/home.html')
If you do not pass instance=the_instance_you_want_to_edit to a ModelForm it will create a new instance. How else would the ModelForm know what model instance you mean to edit?
BaseModelForm.init
if instance is None:
# if we didn't get an instance, instantiate a new one
self.instance = opts.model()
object_data = {}
else:
self.instance = instance
object_data = model_to_dict(instance, opts.fields, opts.exclude)
Anyway, it is not really going to work well if you want to keep it all on one page. Either you manually type in the object_id to pass to the ModelForm later. Or you create a FormSet with each Form representing an Inventory object plus an input field for 'stocks_left'.
The former is a bit iffy because if you mistype the primary key you are going to change the stock of the wrong Inventory without noticing (or throw a DoesNotExist error down the road).
And the latter is total overkill if you only want to change a single Inventory.
You have two options and either option requires another page/template.
One page displays your overview and the other serves to update an Inventory's stock. The overview contains links to the individual update pages.
Capture the primary key of the object you want to edit from the url.
url(r'^myapp/home/([0-9]+)/$)', home, name='home-update')
The URL dispatcher will then call your home view function with the request and the captured parameter and you can instantiate the ModelForm with it.
def home(request, pk):
names = Inventory.objects.all()
if request.method == "POST":
form = Operations(request.POST, instance=Inventory.objects.get(pk=pk)
if form.is_valid():
form.save()
return redirect('myapp/home.html')
else:
form = Operations()
return render(request, 'myapp/a_very_basic_template_to_display_a_form.html', {"form": form})
Or use a class based UpdateView (for your 'update' page):
class InventoryStockUpdateView(views.generic.UpdateView):
model = Inventory
template_name = 'myapp/a_very_basic_template_to_display_a_form.html'
fields = ['stocks_left']
success_url = reverse_lazy('home')
With this in urls.py:
url(r'^myapp/home/(?P<pk>[0-9]+)/$)', InventoryStockUpdateView.as_view(), name='home-update')
To edit Inventory with the primary key 31415 you would then type '...home/31415' into your browser.
UPDATE:
Have you had a look at django's admin actions? They let you edit instances from the changelist by selecting them via a checkbox and then running an admin action on them. While that may not be quite what you want, investigating how exactly they work should teach you some tricks that would help you in your current task.
To maybe give you a few pointers on how to proceed: add <a> tags to your template, two (+/-) for every 'row' of instances you are displaying.
The href attribute of each tag of a should contain the row's instance and the element's 'job' (adding or subtracting a stock). These two values will be used in the url conf much like I described above...
As to how you properly build the href attribute; the template tag docs should help.
Maybe like so:
<tr>
{% for x in names %}
<td align="center"> {{ x }}</td>
<td align="center"> {{ x.inventory_name }}</td>
<td align="center"> {{ x.inventory_code }}</td>
<td align="center"> {{ x.stocks_left }}</td>
<td><a href={% url ??? %}>click me to subtract!</a></td>
<td><a href={% url ??? %}>click me to add!</a></td>
</tr>
{% endfor %}
Of course, you would also need a new view function to handle those urls, but those shouldn't be very difficult to figure out.

Getting Data From the Request Object using Django webframework for MySQL

Hello experts,
I am new in django and trying to learn how to build django web-framework for MySQL database.I can post my query (search term) and get desired results. But I am trying to modify my project so user can submit query in submission page and see their query parameter in URL when it is executed.
Something like this:
submission page: http://localhost:8000/
and after execution page will be like this:http://localhost:8000/xtrack/?searchid=XXXX
But still now I couldn't figure out how to do it in a right way after spending few days.
forms.py
from django import forms
from models import Query
class SQLForm(forms.ModelForm):
xtrackid=forms.CharField(max_length=100)
def checkxID(self):
xtrackid=self.cleaned_data.get("xtrackid")
return xtrackid
class QueryForm(forms.ModelForm):
class Meta:
model=Query
fields=["xtrackid"]
views.py
from django.shortcuts import render
from django.http import HttpResponse
from forms import SQLForm, QueryForm
import sys
def search_form(request):
return render(request, 'index.html')
def search(request):
form = QueryForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
xtrackid = form.cleaned_data.get("xtrackid")
xtrackid =xtrackid.strip()
conn = MySQLdb.connect (host = "localhost", user = "root", passwd = "XXXX", db = "XXXtracker")
cursor = conn.cursor ()
cursor.execute ("SELECT xInfo.xtideID, xIDunID.AccessionNumber FROM xInfo, xIDunID WHERE xInfo.xtideID = xIDunID.xtideID AND xIDunID.xtideID LIKE '%" + xtrackid +"%'")
row = cursor.fetchone ()
listrow= list(row)
contextres={}
if cursor.rowcount==0:
contexterror = {
'outputerror': xtrackid
}
return render(request, 'errorform.html', contexterror)
else:
if contextres.has_key(str(listrow[0])):
contextres[str(listrow[0])].append(listrow[1])
else:
contextres[str(listrow[0])]= [listrow[1]]
resulstdict = {'contextresultinfo': contextres}
return render(request, 'resultform.html', {'xinfo': resulstdict, 'query': xtrackid})
conn.close()
else:
return HttpResponse('Please submit a valid search term.')
urls.py
from django.conf.urls import include, url
from django.contrib import admin
from myapp import views
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^xtrack/$', views.search_form),
url(r'^resultform/$', views.search),
url(r'^errorform/$', views.search)
]
and my templates are like:
index.html
<html>
<h1> Welcome to xTrack </h1>
<head>
<title>Search</title>
</head>
<body>
<form action="/xtrack/" method="get">
<input type="text" name="xtrackid">
<input type="submit" value="Search">
</form>
</body>
</html>
resultform.html
Results
{% if contextresultinfo %}
<table border="1" style="width:100%">
<tr>
<td>xtide tracker ID<br> </td>
<td>Accession number<br></td>
</tr>
{% for key, values in contextresultinfo.items %}
<tr>
{% for items in values %}
<tr>
<td>{{key}}</td>
{% for data in items %}
<td>{{data}}</td>
{% endfor %}
</tr>
{% endfor %}
</tr>
{% endfor %}
</table>
{% else %}
<p>No xtrack matched your search criteria.</p>
{% endif %}
</body>
Can you please give some idea where do I need to change code in my project.
Thanks
in you view, you're getting the submission data through:
form = QueryForm(request.POST or None)
but in you html file, you define your form method as:
<form action="/peptrack/" method="get">
Thus request.POST would't get any data.

NoReverse Match at Delete View

I started coding with Python and Django last week and now I start getting desperate about it.
I have to work on a To-Do-List and want to delete ToDo task by clicking on a button next to the task.
Now I always get a
NoReverseMatch at /delete/1
error :(
The delete_confirm.html:
{% extends "base_page.html" %}
{% block title %}Confirm Todo delete{% endblock %}
{% block content %}
<form action="" method="post">{% csrf_token %}
<p>Are you sure you want to delete "{{ object }}"?</p>
<input type="submit" value="Confirm" />
</form>
{% endblock %}
My Urls.py:
from django.conf.urls import patterns, url
from todolist import views
urlpatterns = patterns('',
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^add', views.AddView.as_view(), name='add'),
url(r'^impressum', views.ImpressumView.as_view(), name='impressum'),
url(r'^edit/(?P<pk>\d+)$', views.UpdateView.as_view(), name='todo_edit'),
url(r'^delete/(?P<pk>\d+)', views.DeleteView.as_view(), name='todo_delete'),
)
The views.py:
from django.shortcuts import render
from django.core.urlresolvers import reverse_lazy
from django.http import HttpResponse
from django.views import generic
from django.views.generic import TemplateView, ListView, CreateView, UpdateView, DeleteView
from todolist.models import Todo
# Create your views here.
class IndexView(ListView):
template_name = 'index.html'
model = Todo
class ImpressumView(TemplateView):
template_name = 'impressum.html'
class AddView(CreateView):
template_name = 'add.html'
model = Todo
fields = ['title','deadline','progress']
success_url = '/'
class UpdateView(UpdateView):
template_name = 'edit.html'
model = Todo
fields = ['title','deadline','progress']
success_url = '/'
class DeleteView(DeleteView):
template_name = 'delete_confirm.html'
model = Todo
success_url = reverse_lazy('/')
The interesting part of the index.html:
<!--Table content-->
{% for todo in object_list %}
<tr>
<td class="text-left">{{todo.title}}</td>
<td> {{todo.deadline}}</td>
<td>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="{{todo.progress}}" aria-valuemin="0" aria-valuemax="100" style="width: {{todo.progress}}%">
{{todo.progress}}%
</div>
</div>
</td>
<td >
<div class="btn-group">
Edit
Delete
<button class="btn btn-default" data-toggle="tooltip" title="Done?" data-placement="right"><span class="glyphicon glyphicon-check"></button>
</div>
</td>
{% endfor %}
Would be great if some of your guys could help a newbie :)
The problem is this line in your delete view.
class DeleteView(DeleteView):
...
success_url = reverse_lazy('/')
You can either provide the url:
success_url = '/'
or use reverse_lazy with the url name that you wish to reverse:
success_url = reverse_lazy('index')

Categories