How can i order my votes by vote count? Django - python

so i made it that my books will show in my admin but i dont know how to order the books(in the admin) by votes and not by last voted. I found some answers here on overflow but i wasnt able to integrate them by myself. Here are my files:
admin.py
from django.contrib import admin
from .models import Vote
admin.site.register(Vote)
apps.py
from django.apps import AppConfig
class SurveyConfig(AppConfig):
name = 'survey'
forms.py
from django import forms
from .models import Vote
class VotingForm(forms.Form):
chosen_books_options = forms.MultipleChoiceField(choices=[], label='Book Name', required=False,
widget=forms.SelectMultiple(
attrs={
'class': 'form-control'
}
))
other_book_name = forms.CharField(label='Other', max_length=100, required=False,
widget=forms.TextInput(
attrs={
'class': 'form-control',
'placeholder': 'Did we miss something?'
}
))
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
unique_books_names = Vote.objects.order_by('book_name').values_list('book_name', flat=True).distinct()
self.fields['chosen_books_options'].choices = [(book_name, book_name) for book_name in unique_books_names]
models.py
from django.db import models, transaction
class Vote(models.Model):
book_name = models.CharField(max_length=200)
count = models.IntegerField(default=0)
def __str__(self):
return '%s: %d votes' % (self.book_name, self.count)
#classmethod
def bulk_vote(cls, book_names):
with transaction.atomic():
for book_name in book_names:
if len(book_name) == 0:
continue
if Vote.objects.filter(book_name=book_name).exists():
Vote.objects.filter(book_name=book_name).update(count=models.F('count') + 1)
else:
Vote.objects.create(book_name=book_name, count=1)
views.py
from django.shortcuts import render
from .forms import VotingForm
from .models import Vote
def index(request):
if request.method == 'POST':
form = VotingForm(request.POST)
if form.is_valid():
chosen_books_options = form.cleaned_data.get('chosen_books_options', [])
other_book_name = form.cleaned_data.get('other_book_name', '')
Vote.bulk_vote(chosen_books_options + [other_book_name])
message = 'Thank You For Your Contribution!'
elif request.method == 'GET':
message = ''
form = VotingForm()
return render(request, 'templates/survey.html', {'form': form, 'message': message})
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<title>Document</title>
<style>
.form-control{
width: 50%;
}
</style>
</head>
<body>
<div class="container" id="thisone">
<h3>Select which books you'd like us to get started with.</h3>
<h5>{{ message }}</h5>
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</body>
thank you for reading
note: this is not fully my code

Within your admin, you can use the ordering attribute like so...
from django.contrib import admin
from .models import Vote
class VoteAdmin(admin.ModelAdmin):
ordering = ('count',)
admin.site.register(Vote, VoteAdmin)

Related

Unable to post data to foreign key table in Django

I am an absolute beginner to Django and I am trying to check the POST method by populating the value to the foreign key table. I have two tables. Please guide me on where I am wrong.
Table for Category that has 2 entries, i.e., Coffee(PK = 1) and Desserts (PK = 2)
Table for Items
From models.py:
class Category(models.Model):
cId = models.AutoField(primary_key=True)
categoryName = models.CharField(max_length=20, unique=True)
def __str__(self):
return self.categoryName
# return[self.categoryName, self.cId]
# return self.cId
class Item(models.Model):
Id = models.AutoField(primary_key=True)
itemName = models.CharField(max_length=30,unique=True)
cId = models.ForeignKey(Category,on_delete=CASCADE)
From views.py:
def main(request):
return render(request, "index.html")
def send(request):
if request.method == "POST":
a = request.POST.get("a");
b = request.POST.get("b");
obj = Item(itemName = a, cId =b);
obj.save()
return HttpResponse("sent")
else:
return HttpResponse("form submission failed")
From urls.py(app):
urlpatterns = [
path('', views.main, name="main"),
path('send', views.send, name='send')
]
From HTML:
<!DOCTYPE html>
<html lang="en">
<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">
{% load static %}
<link rel="stylesheet" href="{% static 'css.css' %}">
<title>CHECK-POST-METHOD</title>
</head>
<body>
<div class = "container">
<form method = "post" action = "send" class = "form">
{% csrf_token %}
<label for="a">Item Name</label>
<input type="text" name="a" id="a" maxlength="30">
<label for="b">PASS FOREIGN KEY--CATEGORY ID</label>
<input type="number" name="b" id="b" maxlength="5">
<button type="submit">SUBMIT</button>
</form>
</div>
<script src="{% static 'js.js' %}"></script>
</body>
</html>
I am unable to populate the Item table with the following entry:
I am unable to resolve the following error:
cId expects a Category object, but you have given it '1'. If you want to specify the primary key instead for a ForeignKey named foo, you use foo_id, so in this case cId_id:
def send(request):
if request.method == 'POST':
a = request.POST.get('a')
b = request.POST.get('b')
obj = Item(itemName=a, cId_id=b)
obj.save()
return HttpResponse("sent")
else:
return HttpResponse("form submission failed")
As it indicates in the error, Cid must be instance of category
So your view looks like below:
def send(request):
if request.method == "POST":
a = request.POST.get("a");
b = request.POST.get("b");
c_id = Category.objects.get(pk=b)
obj = Item(itemName=a, cId=b);
obj.save()
return HttpResponse("sent")
else:
return HttpResponse("form submission failed")
Since cId needs to be an object of type Category, you can use Django's get_object_or_404 function. In cases where cId posted from the HTML is not valid, then this function automatically raises the 404 response.
from django.shortcuts import get_object_or_404
def send(request):
if request.method == "POST":
a = request.POST.get("a");
b = request.POST.get("b");
b_obj = get_object_or_404(Category, b)
obj = Item(itemName = a, cId =b_obj)
obj.save()
return HttpResponse("sent")
else:
return HttpResponse("form submission failed")

How to get the id of a form in Django?

I am trying to develop a page in Django where there is multiple form that the user can modify.
For this, I need to get the id of the form the user ask to modify.
There is my code:
models.py:
class Order(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
date = models.DateField()
forms.py:
class OrderForm(ModelForm):
class Meta:
model = Order
fields = ["date"]
views.py:
def order(request, identifiant):
user_orders = []
form_user_orders = []
user = User.objects.get(username=identifiant) #We use identifiant from the url to get the user
user_orders.append(Order.objects.filter(user=user.id)) #We get all order of the user
if request.method == "POST":
form = OrderForm(request.POST)
if form.is_valid():
order_instance = Order(
id = None, #This is where I have a problem
user=User(id=user.id),
date=form.cleaned_data["date"],
)
order_instance.save()
return HttpResponseRedirect(f"/forms/orders/{identifiant}")
else:
for order in user_orders[0]: #We iterate on all orders and put them in another list as form instances
form_user_orders.append(OrderForm(instance=order))
return render(request, "forms/orders.html", {"identifiant": identifiant, "forms": form_user_orders})
urls.py:
urlpatterns = [
path("orders/<identifiant>", views.order)
]
order.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Order</title>
</head>
<body>
{% for form in forms %}
<form method="POST">
{% csrf_token %}
<div>
<label>Date</label>
<div>
{{ form.date }}
</div>
</div>
</form>
{% endfor %}
</body>
</html>

Python and django: how to set a filter value with a form

I have created the following model that give me the possibility to get all daily income:
class Ricavi(models.Model):
quantita=models.DecimalField()
data_contabile=models.DateField()
After that I have created a views.py that give me the possibility to collect my data in yearly and monthly view as following:
ricavi = dict()
total_ricavi=dict()
for year, month, totale in(Ricavi.objects.values_list( 'data_contabile__year', 'data_contabile__month').
annotate(totale=ExpressionWrapper(Sum(F('quantita') * F('ricavo')*(1+F('iva'))),
output_field=FloatField())).values_list('data_contabile__year', 'data_contabile__month', 'totale')).filter(data_contabile__year=2019):
if id not in ricavi.keys() :
ricavi[id]=list(defaults)
index=month-1
ricavi[id][index]=totale
total_ricavi={'Ricavi Lordi': [sum(t) for t in zip(*ricavi.values())],}
Now I have fixed the data_contabile__year equal to 2019 ad example. But I want to have the possibility to choose the year (ad example using a selection form). How could I get this result?
This is a simple example:
form.py:
from django.forms import IntegerField
class RicaviForm(Form):
Year = IntegerField(label='Year')
view.py:
def ricavi_view(request):
if request.method == 'POST':
form = RicaviForm(request.POST)
if form.is_valid():
# Do somthing with form['Year'].value()
return redirect('stack:ricavi_view')
else:
errors = form.errors
form = RicaviForm()
context = {'form': form, 'ERROR': errors}
return render(request, "stack/ricavi.html", context)
else:
form = RicaviForm()
context = {'form': form}
return render(request, "stack/ricavi.html", context)
ricavi.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="{% url 'stack:ricavi_view' %}" method="POST">
{% csrf_token %}
{{ form }}
<button class="btn btn-primary" name="submit" onclick="submit()">submit</button>
</form>
{{ERROR}}
</body>
</html>
urls.py:
from django.urls import path
from . import views
app_name = 'stack'
urlpatterns = [
path('ricavi', views.ricavi_view, name='ricavi_view'),
]

Cant save forms to models django

i cant save my forms to a models into my database the code work smoothly no errors but if i check in django admin its not save to my database model can you help me
here my code :
forms.py
class InstagramUsernameForm(forms.ModelForm):
class Meta:
model = InstagramUsername
fields = ('nama_orang','username','nama_depan')
nama_orang = forms.CharField(max_length=20)
username = forms.ModelChoiceField(queryset=Instagram.objects.values_list("username", flat=True))
nama_depan = forms.ModelChoiceField(queryset=Instagram.objects.values_list("nama_depan", flat=True))
models.py
from django.db import models
# Create your models here.
class Instagram(models.Model):
nama_depan = models.CharField(max_length=100,blank=True,null=True)
nama_belakang = models.CharField(max_length=100)
username = models.CharField(max_length=100)
def __str__(self):
return self.username
class InstagramUsername(models.Model):
nama_orang = models.CharField(max_length=20)
username = models.CharField(max_length=20)
nama_depan = models.CharField(max_length=100,default='')
def __str__(self):
return self.nama_orang
views.py
def create2(request):
akun_form = InstagramUsernameForm(request.POST or None)
if request.method == 'POST':
if akun_form.is_valid():
akun_form.save()
return redirect('sosmed:awe')
else:
print(akun_form.errors)
context = {
"akun_form":akun_form,
}
return render(request,"sosmed/awe.html",context)
awe.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>awe</title>
</head>
<body>
<form method="post">
{% csrf_token %}
<h1>awe</h1>
<table>
{{ akun_form.as_table }}
</table>
<button type="submit">Create</button>
</form>
</body>
</html>
cant save forms to django models
values_list returns a list of tuples, rather than model instances, when used as an iterable.
so use .all() method instead of values_list()
username = forms.ModelChoiceField(queryset=Instagram.objects.all())

Django get_absoute_url issues?

1- Title link not working. When I click on the link it stays on the same page.
2- Create post not working. I get this error when I press the submit button.
Error message: AttributeError at /post/create/
'Post' object has no attribute 'get_absolute_url'
urls.py
from django.urls import path
from .import views
app_name='post'
urlpatterns = [
path('index/',views.post_index, name='index'),
path('<int:id>/detail',views.post_detail, name='detail'),
path('create/',views.post_create, name='create'),
path('<int:id>/update/',views.post_update, name='update'),
path('delete/',views.post_delete, name='delete'),
]
models.py
from django.db import models
from django.urls import reverse
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=120, verbose_name="Başlık")
content = models.TextField(verbose_name="İçerik")
publishing_date = models.DateTimeField(verbose_name="Yayımlanma Tarihi", auto_now_add=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post:detail', kwargs={'id': self.id})
#return "/post/{}".format(self.id)
views.py
from django.shortcuts import render, get_object_or_404, HttpResponseRedirect
from django.http import HttpResponse
from .models import Post
from .forms import PostForm
def post_index(request):
posts = Post.objects.all()
return render(request, 'post/index.html', {'posts': posts})
def post_detail(request, id):
post = get_object_or_404(Post, id=id)
context = {
'post': post,
}
return render(request, 'post/detail.html', context)
def post_create(request):
#if request.method == "POST":
#print(request.POST)
#title = request.POST.get('title')
#content = request.POST.get('content')
#Post.objects.create(title=title, content=content)
#if request.method == "POST":
#Formdan gelen bilgileri kaydet
#form = PostForm(request.POST)
#if form.is_valid():
#form.save()
#else:
#Formu kullanıcıya göster
#form = PostForm()
form = PostForm(request.POST or None)
if form.is_valid():
post = form.save()
return HttpResponseRedirect(post.get_absolute_url())
context = {
'form': form,
}
return render(request, 'post/form.html', context)
def post_update(request, id):
post = get_object_or_404(Post, id=id)
form = PostForm(request.POST or None, instance=post)
if form.is_valid():
form.save()
return HttpResponseRedirect(post.get_absolute_url())
context = {
'form': form,
}
return render(request, 'post/form.html', context)
def post_delete(request):
return HttpResponse("Burası Post delete sayfası")
index.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
{% for post in posts %}
{{post.id}}<br>
{{post.title}}<br>
{{post.content}}<br>
{{post.publishing_date}}<br>
{% endfor %}
</body>
</html>
Create post form:
forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = [
'title',
'content',
]
form.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form method="POST">
{% csrf_token %}
<h1>Form</h1>
{{form.as_p}}
<input type="submit" value="Gönder">
</form>
</body>
</html>
You have an identation problem on your Post model
from django.db import models
from django.urls import reverse
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=120, verbose_name="Başlık")
content = models.TextField(verbose_name="İçerik")
publishing_date = models.DateTimeField(verbose_name="Yayımlanma Tarihi", auto_now_add=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post:detail', kwargs={'id': self.id})
#return "/post/{}".format(self.id)

Categories

Resources