dropdown box empty in django when trying to populate values from database - python

I am new to Django and I was unable to find a fix for this. I am trying to populate a dropdown box with the database values.
Here are my files
models.py file
from django.db import models
# Create your models here.
class Page(models.Model):
title = models.CharField(max_length=60)
permalink = models.CharField(max_length=12, unique=True)
update_date = models.DateTimeField('Last Updated')
bodytext = models.TextField('Page Content', blank=True)
def __str__(self):
return self.title
class Item(models.Model):
itemId = models.AutoField(primary_key=True)
itemName = models.CharField(max_length = 100, unique=True)
itemPrice = models.IntegerField()
def __str__(self):
return self.itemName
forms.py file
from django import forms
from .models import Item
class OrderListForm(forms.Form):
itemNames = forms.queryset = Item.objects.all().order_by('itemName')
urls.py file
from django.urls import path
from . import views
urlpatterns =[
path('',views.OrderListView.as_view(),name ='hello'),
]
views.py file
from django.views.generic.edit import FormView
from .forms import OrderListForm
# Create your views here.
class OrderListView(FormView):
template_name = "myapp/orderlist.html"
form_class = OrderListForm
context_object_name = 'itemNames'
orderlist.html file
<form action="" method = "post">
{% csrf_token %}
<label for="Items">Choose an Item:</label>
<select id = items >
{% for item in itemNames %}
<option value = "">{{item.itemName}}</option>
{% endfor %}
</form>

Changed the view to listview. I am not sure why I used Formview
Here's the code
views.py
from django.views.generic import ListView
from .models import Item
class OrderListView(ListView):
template_name = "myapp/orderlist.html"
context_object_name = 'itemNames'
def get_queryset(self):
return Item.objects.all()
The other answer is to change the html file to
<form action="" method = "post">
{% csrf_token %}
<label for="Items">Choose an Item:</label>
{{form.as_p}}
</form>

Related

Django: How do I assign a button to take info and save()

Is there a way for the button to do the following? : When user press the button it takes the user.username of the current user and automatically fill up a form of BookInstance from models.py and save it to the database.
From models.py :
class BookInstance(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
book = models.ForeignKey("Book", on_delete=models.RESTRICT, null=True)
imprint = models.CharField(max_length=200, blank=True, null=True)
due_back = models.DateField(blank=True, null=True)
borrower = models.ForeignKey(
User, on_delete=models.SET_NULL, blank=True, null=True)
LOAN_STATUS = (
('m', 'Maintenance'),
('o', 'On Loan'),
('a', 'Available'),
('r', 'Reserved')
)
status = models.CharField(
max_length=1, choices=LOAN_STATUS, blank=True, default='a')
class Meta:
ordering = ['due_back']
def __str__(self):
return f'{self.id} - {self.book.title}'
def get_absolute_url(self):
return reverse("catalog:book_list")
class Book(models.Model):
title = models.CharField(max_length=50)
author = models.ForeignKey(
'Author', on_delete=models.SET_NULL, null=True)
summary = models.TextField(
max_length=500, help_text="Enter brief description")
isbn = models.CharField('ISBN', max_length=13, unique=True)
genre = models.ManyToManyField(Genre, help_text="Select genre")
language = models.ForeignKey(
"Language", on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("catalog:book_detail", kwargs={"pk": self.pk})
This is my from my views.py :
def borrowBook(request, pk):
context = {
'book_instance': BookInstance.objects.all()
}
success_url = reverse_lazy('catalog:index')
if request.method == "POST":
form = BorrowForm(request.POST or None)
if form.is_valid():
book_instance.id = BookInstance.objects.get(pk=pk)
book_instance.book = BookInstance.objects.get(book=book)
book_instance.borrower = request.user
book_instance.status = 'o'
book_borrowed_count = BookInstance.objects.filter(
owner=request.user).count()
if book_borrowed_count < 4:
book_instance = form.save(commit=False)
book_instance.save()
else:
print("Maximum limit reached!")
return redirect('catalog:index')
return render(request, 'catalog/book_detail.html', {'form': form})
here's from my BorrowForm from forms.py :
class BorrowForm(forms.ModelForm):
class Meta:
model = BookInstance
fields = '__all__'
here's my from my urls.py :
path("book_list/book/<int:pk>/borrow", views.borrowBook, name="borrowBook"),
I also tried using a CBV here:
class BorrowBookView(PermissionRequiredMixin, CreateView):
permission_required = 'login'
model = BookInstance
fields = '__all__'
template_name = 'catalog/borrow_form.html'
success_url = reverse_lazy('catalog:index')
def post(self, request, *args, **kwargs):
book_instance.id = BookInstance.objects.get(pk=pk)
book_instance.book = BookInstance.objects.get(book=book)
book_instance.borrower = request.user
book_instance.status = 'o'
book_instance = form.save(commit=False)
book_instance.save()
CBV path from urls.py :
path("book_list/book/<int:pk>/borrow/",
views.BorrowBookView.as_view(), name="book_borrow"),
Here's how I implemented the button using suggestions from here:
<form action="#" method="post">
{% csrf_token %}
<button
type="submit"
class="btn btn-dark flex-shrink-0 "
value="{{ book.id }}">Borrow
</button>
but when I pressed it doesn't seem to save anything to the database and just popup errors, though I may implemented the button or the function from my is views wrong. Thanks and appreciate for any help provided.
You do not need a Django form for this. Forms are usually used for when you want to create objects or edit its fields (like in the admin page). While here an user is not editing nor creating an object (book), but borrowing one.
So basically, we just need to list all available book instances (status='a'), and have a button to "borrow" it. The borrow action is to update status to 'r' or 'o' and have the borrower updated to the current user which is guaranteed to exist inside the request object by LoginRequiredMixin
views.py
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views import View
from django.contrib import messages
from django.urls import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from .models import BookInstance
class BorrowBook(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs):
book_id = kwargs['pk']
available_books = BookInstance.objects.filter(book__pk=book_id, status='a')
return render(request, 'borrow_book.html', {'available_books': available_books})
def post(self, request, *args , **kwargs):
book_instance_id = request.POST['id']
obj = get_object_or_404(BookInstance, id=book_instance_id)
obj.status = 'r'
obj.borrower = request.user
# Maybe also update due_back data
# obj.due_back = ...
obj.save()
messages.success(request, "Your book is reserved.")
# I used the redirection to the same template
# But you probably want to send the user somewhere else
return HttpResponseRedirect(reverse('core:borrow-book', kwargs={'pk': 1}))
borrow_book.html
{% extends 'base.html' %}
{% block content %}
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% for instance in available_books %}
<form action="{% url 'core:borrow-book' instance.book.id %}" method="POST">
{% csrf_token %}
<input type="hidden" name="id" value="{{instance.id}}">
<p>{{instance.book}}</p>
<p>{{instance.book.language.name}}</p>
<input type="submit" value="Borrow this book.">
</form>
{% endfor %}
{% endblock content %}
urls.py
from django.urls import path
from core import views
app_name = 'core'
urlpatterns = [
path("book_list/book/<int:pk>/borrow/", views.BorrowBook.as_view(), name="borrow-book"),
]

How can I solve ValueError in django. Exception Value: ModelForm has no model class specified

This is my code:
django.models. my model.py file
from django.db import models
class Product(models.Model):title = models.CharField(max_length=150)
description = models.TextField(blank=True, null=True)
price = models.DecimalField(decimal_places=2, max_digits=100000)
summary = models.TextField(blank=True, null=False)
featured = models.BooleanField(default=False)
forms.py That's my full form.py file
from django import forms
from .models import Product
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = [
'title',
'description',
'price',
]
class RawProductForm(forms.ModelForm):
title = forms.CharField()
description = forms.CharField()
price = forms.DecimalField()
django.views my django.views file
from django.shortcuts import render
from .models import Product
from .forms import ProductForm, RawProductForm
def product_create_view(request):
my_form = RawProductForm()
if request.method == 'POST':
my_form = RawProductForm(request.POST)
if my_form.is_valid():
print(my_form.cleaned_data)
Product.objects.create(**my_form.cleaned_data)
else:
print(my_form.errors)
context = {'form': my_form}
return render(request, "products/product_create.html", context)
products_create.html this is my html file
{% extends 'base.html' %}
{% block content %}
<form action="." method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save" />
</form>
{% endblock %}
In his code I'm trying to make a form but when I run python manage.py runserver at http://127.0.0.1:8000/create/ I'm getting ValueError
This is a screenshot of my full error messagae
You need to specify your model class in your form :
class RawProductForm(forms.ModelForm):
class Meta:
model = Product
fields = ["price","description" ,"title"]
view :
def product_create_view(request):
my_form = RawProductForm()
if request.method == 'POST':
my_form = RawProductForm(request.POST)
if my_form.is_valid():
print(my_form.cleaned_data)
Product.objects.create(**my_form.cleaned_data)
else:
print(my_form.errors)
context = {'form': my_form}
return render(request, "products/product_create.html", context)

django.core.exceptions.FieldError: Cannot resolve keyword 'productcategory_id' into field. Choices are: country, country_id, id, name, vendor?

I am trying to use here Django dependent dropdown list. But at the same time, the error occurred. If I make an ajax request click the product category and the dependent dropdown not working togetherly and cannot make an ajax request shows an error. How to resolve this error? Can please someone help me to clear this issue.
Models.py
from django.db import models
class ProductCategory(models.Model):
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class SubCategory(models.Model):
country = models.ForeignKey(ProductCategory, on_delete=models.CASCADE)
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class Vendor(models.Model):
designer_name = models.CharField(max_length=100, default='')
design_name = models.CharField(max_length=200)
description = models.TextField(max_length=5000)
productcategory = models.ForeignKey(ProductCategory, on_delete=models.SET_NULL,
null=True)
subcategory = models.ForeignKey(SubCategory, on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.designer_name
forms.py
from django import forms
from .models import Vendor, ProductCategory, SubCategory
class DesignerForm(forms.ModelForm):
class Meta:
model = Vendor
descr = forms.CharField( widget=forms.Textarea )
fields = ('designer_name','design_name', 'description', 'productcategory', 'subcategory')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['subcategory'].queryset = SubCategory.objects.none()
if 'productcategory' in self.data:
try:
productcategory_id = int(self.data.get('productcategory'))
self.fields['subcategory'].queryset = SubCategory.objects.filter(productcategory_id=productcategory_id).order_by('name')
except (ValueError, TypeError):
pass # invalid input from the client; ignore and fallback to empty City queryset
elif self.instance.pk:
self.fields['subcategory'].queryset = self.instance.productcategory.subcategory_set.order_by('name')
Views.py
from .models import *
from django.shortcuts import render, redirect
from .forms import *
def Products(request):
if request.method == 'POST':
form = DesignerForm(request.POST)
if form.is_valid():
form.save()
return redirect('Products')
else:
form = DesignerForm()
return render(request, 'jinja2/products.jinja',{'form': form})
def ajax_load_subcategories(request):
productcategory_id = request.GET.get('productcategory')
subcategories =
SubCategory.objects.filter(productcategory_id=productcategory_id).order_by('name')
return render(request, 'jinja2/city_dropdown_list_options.jinja', {'subcategories':
subcategories})
admin.py
from django.contrib import admin
from boutique_store.models import Vendor, ProductCategory, SubCategory
# Register your models here.
admin.site.register(ProductCategory)
admin.site.register(SubCategory)
admin.site.register(Vendor)
urls.py
from django.urls import include, path
from . import views
urlpatterns = [
path('add/', views.Products, name='Products'),
path('ajax/load_subcategories/', views.ajax_load_subcategories,
name='ajax_load_subcategories'), # <-- this one here
]
products.jinja
{% block content %}
<h2>Person Form</h2>
<form method="post" id="designerForm" data-subcategories-url="{% URL
'ajax_load_subcategories' %}" novalidate>
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<button type="submit">Save</button>
</form>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous">
</script>
<script>
$("#id_productcategory").change(function () {
var url = $("#designerForm").attr("data-subcategories-url");
var productcategoryId = $(this).val();
$.ajax({
url: URL,
data: {
'productcategory': productcategoryId
},
success: function (data) {
$("#id_subcategory").html(data);
}
});
});
</script>
{% endblock %}
city_dropdown_list_options.jinja
<option value="">---------</option>
{% for subcategory in subcategories %}
<option value="{{ subcategory.pk }}">{{ subcategory.name }}</option>
{% endfor %}
In SubCategory model you have a field named country which refers to ProductCategory. You can't filter with productcategory_id because there is no such column/field in current model.
class SubCategory(models.Model):
country = models.ForeignKey(ProductCategory, on_delete=models.CASCADE)
name = models.CharField(max_length=30)
def __str__(self):
return self.name
So try to fix your queries like below in forms.py and views.py :
SubCategory.objects.filter(country_id=productcategory_id).order_by('name')

Django version 3.1.3 form not saving to model

I am following this tutorial
I have gone back and written the code to match exactly. I have another form that works called category_add which is exactly the same as this form. But for the life of me I cannot figure out why bookmark_add doesn't update the database with the form entries.
Models.py
from django.db import models
from django.contrib.auth.models import User
class Category(models.Model):
title = models.CharField(max_length=255)
description = models.TextField(blank=True, null=True)
created_by = models.ForeignKey(User, related_name='categories', on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'Categories'
def __str__(self):
return self.title
class Bookmark(models.Model):
category = models.ForeignKey(Category, related_name='bookmarks', on_delete=models.CASCADE)
title = models.CharField(max_length=255)
description = models.TextField(blank=True, null=True)
url = models.CharField(max_length=255, blank=True)
created_by = models.ForeignKey(User, related_name='bookmarks', on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
View.py
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .forms import BookmarkForm
#login_required
def bookmark_add(request, category_id):
if request.method == 'POST':
form = BookmarkForm(request.POST)
if form.is_valid():
bookmark = form.save(commit=False)
bookmark.created_by = request.user
bookmark.category_id = category_id
bookmark.save()
return redirect('category', category_id=category_id)
else:
form = BookmarkForm()
context = {
'form': form
}
return render(request, 'bookmark/bookmark_add.html', context)
Forms.py
from django.forms import ModelForm
from .models import Bookmark
class BookmarkForm(ModelForm):
class Meta:
model = Bookmark
fields = ['title', 'description', 'url']
Urls.py
path('', dashboard, name='dashboard'),
path('categories/', categories, name='categories'),
path('categories/add/', category_add, name='category_add'),
path('categories/<int:category_id>/', category, name='category'),
path('categories/<int:category_id>/add_bookmark', bookmark_add, name='bookmark_add')
]
bookmark_add.html
{% extends 'core/base.html' %}
{% block content %}
<div class="container">
<h1 class="title">Add link</h1>
<form method="post" action=".">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="button is-primary">Submit</button>
</form>
</div>
{% endblock %}
Solved this!
This was a dumb issue and an oversight on my end. Thanks to the content creator on youtube. I just needed to append "/" to the url path for add_bookmark.
Problem:
path('categories/<int:category_id>/add_bookmark', bookmark_add, name='bookmark_add')
The Fix:
path('categories/<int:category_id>/add_bookmark/', bookmark_add, name='bookmark_add')

Retrieve polygon from Django postgis database and display it to the browser

I tried to retrieve the polygon which I saved into postgis database. (all polygons)
Here is my code:
models.py
from django.contrib.gis.db import models
class MyMap(models.Model):
name = models.CharField(max_length=50, blank=True, null=True)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
geom = models.GeometryCollectionField(srid=4326, null=True)
objects = models.GeoManager()
def __unicode__(self):
return self.name
forms.py
from django.contrib.gis import forms
from .models import MyMap
class MyMapForm(forms.ModelForm):
class Meta:
model = MyMap
fields = ['geom']
views.py
from django.shortcuts import render
from django.http import HttpResponse
from .forms import MyMapForm
from .models import MyMap
def map(request):
map_info = MyMap.objects.all()
map_data = {
"map_detail": map_info
}
return render(request, 'mymap.html', map_data)
def ajax(request):
if request.POST.has_key('geom'):
form = MyMapForm(request.POST or None)
...
mymap.html
<form action="" method="POST">
{%csrf_token%}
<div id="map_canvas"></div> // I use google map api
</form>
<div>
{% for details in map_detail %}
{{detail.geom}}
{% endfor %}
</div>
I don't know where is my problem which I can not show the polygons in the html file !
EDIT#1
EDIT#2

Categories