Unable to post data to foreign key table in Django - python

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")

Related

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'),
]

How can i order my votes by vote count? Django

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)

Display the field value based on the value selected from the drop down in django forms

I am a newbie!! I have a task to populate a field value based on the option selected from the drop down menu.
Forms.py
from django import forms
from .models import MainPage
import datetime
from datetime import date
techlist = (
('DateOfDrive', 'DateOfDrive'),
('NameOfDrive', 'NameOfDrive'),
('Status', 'Status'),
('Marks_Scored', 'Marks_Scored'),
('First_Round_Interviewer_Name', 'First_Round_Interviewer_Name'),
('Second_Round_Interviewer_Name', 'Second_Round_Interviewer_Name'),
('Third_Round_Interviewer_Name', 'Third_Round_Interviewer_Name'),
('Management_Round_Interviewer_Name', 'Management_Round_Interviewer_Name'),
('HR_Round_Interviewer_Name', 'HR_Round_Interviewer_Name')
)
class analysisForm(forms.Form):
GroupBy = forms.ChoiceField(choices=techlist)
where = forms.CharField()
datefrom = forms.DateField(initial="2019-01-01")
dateto = forms.DateField(initial=date.today())
views.py
class analysis(FormView):
template_name = 'analysis.html'
# View for the analysis page
def get(self, request):
form = analysisForm()
return render(request, self.template_name, {'form': form})
def post(self, request):
form = analysisForm(request.POST)
if form.is_valid():
groupbyf = form.cleaned_data['GroupBy'] # Getting the groupby otpion from the user
wheref = form.cleaned_data['where'] # Getting the search element from the user
datetof = form.cleaned_data['dateto'] # Getting the end date from the user
datefromf = form.cleaned_data['datefrom'] # Getting the from date from the user
# Loading the excel to data frame
query = str(Summary.objects.all().query)
df_view_summary = pd.read_sql_query(query, connection)
print(df_view_summary)
# Extracting the month number from the complete date
df_view_summary['Month'] = pd.DatetimeIndex(df_view_summary['DateOfDrive']).month
analysis.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
<table>
{{ form.as_p }}
</table>
<input type="submit">
</form>
# Loading the excel to data frame
query = str(Summary.objects.all().query)
df_view_summary = pd.read_sql_query(query, connection)
print(df_view_summary)
# Extracting the month number from the complete date
df_view_summary['Month'] = pd.DatetimeIndex(df_view_summary['DateOfDrive']).month
</body>
</html>
What changes should I do now to populate the where field in django based on the value selected from drop down groupby field in the form. As soon as a value is selected in the drop down populate the where field with values which would be sent by views.
How to do this without ajax/Javascript.

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())

Categories

Resources