I am trying to display a ListView of items that when clicked opens the respective DetailView for that item. This is a pretty straightforward thing to do in Django, but I'm running into some trouble with it.
I have successfully created a ListView, but I can't get the DetailView to display the information for each item.
I am building a password safe. The ListView lists all the passwords saved, and the DetailView is the view/edit page for each password. And yes, I realize actually putting a password safe on the internet is a terrible idea, it's just a test project :)
My PasswordSafe class:
class PasswordSafe(models.Model):
user = models.OneToOneField(User)
pwWebsite = models.CharField(max_length=30)
pwUsername = models.CharField(max_length=30)
pwEmail = models.CharField(max_length=30)
pwPassword = models.CharField(max_length=30)
def __unicode__(self): # __unicode__ on Python 2, __str__ on Python 3
return self.pwWebsite
User.passwordSafe = property(lambda u: PasswordSafe.objects.get_or_create(user=u)[0])
My urls.py:
from django.conf.urls import patterns, include, url
from django.views.generic import ListView, DetailView
from models import PasswordSafe
urlpatterns = [
url(r'^passwordSafe/$', ListView.as_view(queryset=PasswordSafe.objects.all().order_by('-pwWebsite')[:10], template_name = 'userprofile/passwordSafe_list.html')),
url(r'^passwordSafe/(?P<pk>\d+)/$', DetailView.as_view(model=PasswordSafe, template_name='userprofile/passwordSafe.html')),
]
I use the following code successfully in my ListView template (passwordSafe_list.html):
{% for passwordSafe in object_list %}
<h2>{{ passwordSafe.pwWebsite }}</h2>
{% endfor %}
However, when I try to use the passwordSafe data in my Detailview (the passwordSafe.html template), nothing shows up. I use the following code to try and change the title:
<title>{% block title %} | Edit {{ passwordSafe.pwWebsite }} Password{% endblock %}</title>
This should show a title something like "Password Safe | Edit Google Password", but passwordSafe.pwWebsite returns with nothing. Am I doing something wrong in trying to reference passwordSafe from this template? I know I haven't passed a query set like I did with the ListView, but I'm not sure if that's part of the problem or not.
In the DetailView, Django uses the model name in lowercase, by default, if you haven't set context_object_name.
{{ passwordsafe.pwWebsite }}
Related
I have a class that passes in a django ListView. From this ListView I can access my DB items. My problem is that accessing the db using the list view will load all the entries. what if I just want one entry, say the 5th entry for example. Maybe listView is the wrong type of view to be using? my code below work and shows my DB entries on-screen as a list.
models.py
from django.db import models
class Datadata(models.Model):
text = models.TextField()
views.py
class HomePageView(ListView):
model = Datadata
template_name = 'hello.html'
templates/hello.html
{% for post in object_list %}
<h1>{{ post.text }}</h1>
{% endfor %}
Then you normally use a DetailView [Django-doc]. You can for example define this as:
from django.views.generic.detail import DetailView
class HomePageView(DetailView):
model = Datadata
template_name = 'hello.html'
You can then render this for example with:
<h1>{{ object.text }}</h1>
What is convenient is that a DetailView, just like all views with a SingleObjectModelMixin [Django-doc] autoamtically filter on the primary key pk or slug field.
So the url pattern should look like:
urlpatterns = [
path('data/<int:pk>/', HomePageView.as_view(), name='data-detail'),
]
If we then access /data/5 for example, it will show the data for the item with as primary key 5.
New to Django, and I'm stuck on a problem. I have several buttons on a page, each is an instance of a simple Color object I created. The object has attributes of 'name'(string),'hex'(string), and 'count'(integer). I want to be able to keep track of how many times each button is pressed; so, for example, if someone presses the button associated with 'Red,' it will Post to the database that the 'count' attribute for Red should increment by 1.
This is basically how the 'vote' function works in the app they show in the Django documentation, but I cannot figure out how to apply it to my program, even though mine is simpler. Any advice is appreciated. Please let me know if I've posted enough code to determine the issue.
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.template import loader
from .models import Color
### function in question ###
def detail(request, colorname):
bodybg = colorname
colorslist = Color.objects.all()
colorcount = 0
for color in colorslist:
if colorname == color.hex:
colorcount = color.count
colorCounterObj = get_object_or_404(Color, pk=colorcount)
selected_color = colorCounterObj.choice_set.get(pk=request.POST['choice'])
selected_color.count += 1
selected_color.save()
context = {
'bodybg' : bodybg,
'colorslist' : colorslist,
'colorcount' : colorcount,
}
template = loader.get_template('colortime/detail.html')
return HttpResponse(template.render(context, request))
<!-- HTML on my index page, where the buttons are. Makes a list of buttons in different colors, that works just fine. Not sure if my 'formaction' is worded properly or really even functional -->
<body>
<center>
{% if colorslist %}
<ul>
{% for color in colorslist %}
<li ><h3 class='button' style='background-color:{{ color.hex }};' formaction="{% url 'colortime:detail' color %}" method="post" name='choice'>{{ color.name }}</h3></li>
{% endfor %}
</ul>
{% else %}"
<p>No colors here.</p>
{% endif %}
</center>
</body>
Right now the error I'm getting is:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/color/0000FF/
Raised by: colortime.views.detail
No Color matches the given query.
The url varies slightly based on which button I press but they all do this.
Edit: Models.py and Urls.py below
from django.urls import path
from . import views
app_name = 'colortime'
urlpatterns = [
path('', views.index, name='index'),
path('<str:colorname>/', views.detail, name='detail'),
]
from django.db import models
from django import forms
# Create your models here.
class Color(models.Model):
hex = models.CharField(max_length=6)
name = models.CharField(max_length=50)
count = models.IntegerField(default=0)
def __str__(self):
return self.name
I am a newbie to django and need some help. I have a created a vaguely functioning website. I have a model which looks as follows;
from django.db import models
class InductiveSensors(models.Model):
Part_No = models.CharField(max_length=250)
Manufacturer = models.CharField(max_length=250)
Sn = models.CharField(max_length=250)
AssuredSn = models.CharField(max_length=250)
def __str__(self):
return InductiveSensors.Manufacturer
There are a couple of pages. one which gives me a list of all items in the database
{% extends "ESensFind/header.html" %}
{% block content %}
{% for InductiveSensors in object_list %}
<h5>{{ InductiveSensors.Manufacturer}}<a
href="/Inductive_Search/{{InductiveSensors.id}}">
{{InductiveSensors.Part_No}}</a></h5>
{% endfor %}
{% endblock %}
When the {{InductiveSensors.Part_No}} link is clicked it opens up another page. On which I would like to display this database entry in a table with the information of
Part_No = models.CharField(max_length=250)
Manufacturer = models.CharField(max_length=250)
Sn = models.CharField(max_length=250)
AssuredSn = models.CharField(max_length=250)
my urls look like:
from django.conf.urls import url, include
from django.views.generic import ListView, DetailView
from Inductive_Search.models import InductiveSensors
urlpatterns = [
url(r'^$',ListView.as_view(queryset=InductiveSensors.objects.all().order_by
("Manufacturer") #THIS PAGE IS THE LIST OF ALL DATABASE ENTRIES#
[:25],template_name="Inductive_Search/Inductive_Search.html")),
url(r'^(?P<pk>\d+)$', ListView.as_view(model= InductiveSensors,
template_name = 'Inductive_Search/SensorInfo.html')) #THIS OPENS UP A NEW
INDEX PAGE AFTER A PARTICULAR DATABASE ENTRY LINK IS CLICKED#
is the 2nd url code correct to work in conjunction with "SensorInfo.html"? In "SensorInfo.html" i have this code, which I would think should display even just the manufacturer information in a header but it displays nothing.
{% extends "ESensFind/header.html" %}
{% block content %}
<h5>{{ InductiveSensors.Manufacturer}}</h5>
{% endblock %}
Essentially what I am trying to do is get SensorInfo.html to display the values from my model, relating to that particular index in a table on my webpage. Any help would be appreciated. Thanks
The "right" solution is to write detail view (by deriving from DetailView), when in the template you can access the underlying object using get_object() or .object.
If you want to implement it quick and dirty, you have to access the pk argument and using it get the model instance, and pass it as part of the context data.
I suggest you dig into documentation, the django tutorial is good place to start (https://docs.djangoproject.com/en/2.0/intro/tutorial01/#writing-your-first-django-app-part-1) or read on class based views here https://docs.djangoproject.com/en/2.0/topics/class-based-views/generic-display/
So would a solution be something like the following to urls.py?
from django.conf.urls import url, include
from django.views.generic import ListView, DetailView
from Inductive_Search.models import InductiveSensors
urlpatterns = [
url(r'^$',
ListView.as_view(queryset=InductiveSensors.objects.all().order_by
("Manufacturer")
[:25],template_name="Inductive_Search/Inductive_Search.html")),
url(r'^(?P<pk>\d+)$', DetailView.as_view(model= InductiveSensors,
template_name = 'Inductive_Search/SensorInfo.html'))
]
and in the template
{% extends "ESensFind/header.html" %}
{% block content %}
<h5>{{ get_object() }}</h5>
{% endblock %}
I'm currently building an app with Django for the purpose of creating user-story cards (a bit like a Trello board).
On one page I have my cards displayed as a list:
The code for the list is:
<h1>ScrumBuddy Board</h1>
<ul>
{% for card in cards.all %}
<li class="card">{{ card.title }}
</li>
{% endfor %}
</ul>
And the view def for the board is:
def board(request):
cards = Card.objects
context = {'cards': cards}
return render(request, 'scrumbuddy/board.html', context)
I'd like to add a delete link to each card that removes it from this list, preferable with a confirmation dialogue box. Any suggestions on how to do that would be fantastic.
Many thanks.
I'd suggest using Django's generic class-based views, in your case you would probably use ListView and DeleteView.
For a list view, you could use something like this:
# views.py
from django.views.generic import ListView
from scrumbuddy.models import Card
class CardList(ListView):
model = Card
And for the delete view something like this:
# views.py
from django.views.generic.edit import DeleteView
from django.urls import reverse_lazy
from scrumbuddy.models import Card
class CardDelete(DeleteView):
model = Card
success_url = reverse_lazy('card-list')
As far as the confirmation for the delete action goes, from the Django documentation on the DetailView topic:
A view that displays a confirmation page and deletes an existing
object. The given object will only be deleted if the request method is
POST. If this view is fetched via GET, it will display a confirmation
page that should contain a form that POSTs to the same URL.
Also, note that you can pass arguments to the url template tag, e.g.:
<a href="{% url 'card' id=card.id %}">
instead of:
<a href="{% url 'card' %}/{{ card.id }}">
Note: I guessed that the card.id parameter to your card url is named id - you'll have to update this as per your urls.py if the parameter is named differently.
I'm trying to work out how to have suggestions in a text field using Django (1.11). I've been going through the documentation of autocomplete-light but so far I've not been able to figure out my use case. The documentation on that package is not easy to understand for a total noob :)
I want a text field that gives suggestions as you type, were the suggestions come from the database.
E.g. if it's a list of food items the user types in 'C' and it suggest Chicken and Crisps as they have been entered by someone earlier. I also want the user to be able to enter Cheese even though it hasn't been entered before.
The suggestion "algorithm" just has to check if what has been entered matches the first characters of already existing items.
Here is a boiled down version of the django project:
urls.py
from django.conf.urls import url
from django.contrib import admin
from testapp.views import TestView
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'$',TestView.as_view())
]
models.py
from django.db import models
class TestModel(models.Model):
name = models.CharField(max_length=120)
def __str__(self):
return self.name
forms.py
from django import forms
from .models import TestModel
class TestFormClass(forms.ModelForm):
class Meta:
model = TestModel
fields = ('__all__')
views.py
from django.shortcuts import render
from django.views.generic import CreateView
from .forms import TestFormClass
class TestView(CreateView):
form_class = TestFormClass
template_name = 'template.html'
success_url = "/"
template.html
<html>
<header><title>This is title</title></header>
<body>
Enter something <br>
{% block content %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
{% endblock %}
</body>
</html>
I'm hoping someone has a relatively simple solution to add the this code, at the moment I'm not worried about authentication or anything, just looking for a basic solution.
You can make use of django-autocomplete-light