HTML form data not saved in database - django - django

I can get data from html but it wont save to database what should i do ?
it works correctly the only problem is that it wont be save
views.py
def comment(request , newsId):
cm = get_object_or_404(models.News , id= newsId)
print("news = " + newsId)
if request.method == 'POST' :
cm.comments_set.text = request.POST.get('comment_text')
cm.comments_set.name = request.POST.get('comment_name')
cm.save()
return HttpResponseRedirect(reverse('details', args=(cm.id,)))
urls.py
urlpatterns = [
path('', views.test),
path('details/<newsId>', views.details, name="details"),
path('comment/<newsId>' , views.comment ,name="comment")]
models.py
class News(models.Model):
title = models.CharField(max_length=300)
author = models.CharField(max_length=100)
date = models.DateTimeField()
description = models.TextField()
like = models.IntegerField(default=0)
img = models.CharField(max_length=100)
def __str__(self):
return self.title
class Comments(models.Model):
news = models.ForeignKey(News, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
text = models.TextField()
def __str__(self):
return self.name
html form
<form action="{% url 'comment' newsKey.id %}" method="POST">
{% csrf_token %}
<textarea name="comment_text" id="comment_text_id" cols="30" rows="10" placeholder="Write your here comment here"></textarea>
<input type="text" name="coment_name" id="comment_name_id" placeholder="Type full name"/>
<button type="submit" value="comment_submit"> SUBMMIT </button>
</form>

What you're doing here is saving the original News object (not a Comment) after settings some random properties on the comments_set.
Basically you're shooting blanks :)
# fix this part.
news_article = get_object_or_404(models.News, id=newsId)
comment = models.Comment(
name=request.POST.get('comment_name' , ''),
text=request.POST.get('comment_text',''),
news=news_article
)
comment.save()
The comment_set is used to select all the related comments to the given News article.
See this django tutorial.
The above can also be shortened by using the create method like so:
models.Comment.objects.create(
name=request.POST['comment_name'],
text=request.POST['comment_text'],
news=news_article
)
This method also saves to the database.

Related

how to select an item multiple time in django m2m field in form

I am a beginner and learning django, here i want to let the user to select items multiple times in a m2m field, for example here i have a icecream model with flavor class linked to it in a m2m rel, when the form is displayed in the template i want user to select 1 option many times.
my models:
class IceCream(models.Model):
hold_choice = (
('Cone', 'Cone'),
('Cup','Cup'),
)
type_name = models.ForeignKey('IceCreamType', on_delete=models.CASCADE, null=True, blank=True)
flavor = models.ManyToManyField(Flavor, verbose_name='total scopes')
toppings = models.ManyToManyField(Topping)
holder = models.CharField(max_length=4, choices=hold_choice, default='Cone')
number_of_icecreams = models.PositiveIntegerField(default=1)
def __str__(self):
return str(self.type_name)
#property
def total_scope(self):
return self.flavor_set.all().count()
the flavor model has some options:
class Flavor(models.Model):
CHOCOLATE = 'Chocolate'
VANILLA = 'Vanilla'
STRAWBERRY = 'Strawberry'
WALLNUT = 'Wallnut'
KULFA = 'Kulfa'
TUTYFRUITY = 'Tuttyfruity'
choices = (
(CHOCOLATE, 'chocolate scope'),
(VANILLA, 'vanilla scope'),
(STRAWBERRY, 'strawberry scope'),
(WALLNUT, 'wallnut scope'),
(KULFA, 'kulfa scope'),
(TUTYFRUITY, 'tutyfruity scope'),
)
flavor = models.CharField(max_length=20, choices=choices, null=True)
def __str__(self):
return self.flavor
now if i display the form for it, how could it be possible for user to select 1 item(or scopes) many times, and also the method i've created in IceCream model doesnt work and gives the error IceCream has no attribute flavor_set.
the view for it to display
class OrderIceCream(CreateView):
model = IceCream()
template_name = 'prac/home.html'
fields = '__all__'
template:
<h1 class="text-center mt-5">Order Ice Cream</h1>
<div class="container border-dark">
<form action="" method="post">
{% csrf_token %}
{{ form|crispy }}
<input type="submit" class="btn btn-primary mb-3 mt-3">
</form>
</div>
url is:
urlpatterns = [
path('home/<str:pk>/', IceCream.as_view(), name='home'),
path('order/<str:pk>/', OrderIceCream.as_view(), name='order-icecream'),
]
form on site image

How to fix add to cart functionality in django?

I'm building an ecommerce platform and I want to create the add to cart functionality in the website. But for some reason the Product Id is showing null.
Here's the codes:
models.py
class Products(models.Model):
user = models.ForeignKey(User, on_delete = models.CASCADE)
title = models.CharField(max_length = 255)
product_category = models.CharField(choices = CATEGORY_CHOICES, max_length = 100)
description = models.TextField()
price = models.FloatField(max_length= 5)
class Cart(models.Model):
user = models.ForeignKey(User, on_delete = models.CASCADE)
products = models.ForeignKey(Products, on_delete = models.CASCADE)
views.py
def add_cart(request):
product_id = Products.id
new_product = Cart.objects.get_or_create(id=product_id, user=request.user)
return redirect('/')
templates
<div class="product-wrapper">
<h1 style="font-size:24px">{{product.title}}</h1>
<div class="product-price">
<p style="text-decoration-line:line-through;">$ {{product.price}}</p>
<a href="{% url 'add-product' product.product_id %}">Add to cart<a>
</div>
When I try to click this link it gives me this error: Field 'id' expected a number but got <django.db.models.query_utils.DeferredAttribute object at 0x000002468A4F8550>.
Any suggestion will be really helpful. Thank you
Finally, I've fixed this.
view.py
def add_to_cart(request, slug):
products = Products.objects.get(slug=slug)
ncart = Cart.objects.create(user=request.user, products=products)
ncart.save()
return redirect('/')
template
<div class="product-wrapper">
<h1 style="font-size:24px">{{product.title}}</h1>
<div class="product-price">
<p style="text-decoration-line:line-through;">$ {{product.price}}</p>
<a href="{% url 'add-to-cart' product.slug %}">Add to cart<a>
</div>
urls.py
path('cart/add/<slug:slug>', views.add_to_cart, name = 'add-to-cart')
Considering you've got Products instance already, in that case
Query directly like:
new_product = Cart.objects.get_or_create(products=Products)
If you want to query from the product_id, do it like that:
product_id = Products.pk
new_product = Cart.objects.get_or_create(products_id=product_id)
In addition:
request.user contains a dictionary, you can't pass it directly to query. And the user field has name buyer, so change that query like that:
product_id = Products.pk
new_product = Cart.objects.get_or_create(products=Products, buyer_id=request.user['pk'])

Django empty list when using ModelChoiceField

First of all, I'm new to Django or MVC frameworks in general and I've got quite little experience in Python.
I've read stackoverflow threads with similar title, but yet I'm missing some puzzle piece.
After trying for some time, this is what I ended up with... which renders empty list. I think it's due to the fact, that the referred table has no database entries. I can't seem to figure out how to evaluate values based on FK from another table:
models.py
class Employees(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
def __str__(self):
return self.last_name
def get_absolute_url(self):
return reverse('employees')
class Tasks(models.Model):
type = models.CharField(max_length=30)
duration = models.IntegerField()
def __str__(self):
return self.type
def get_absolute_url(self):
return reverse('tasks')
class Records(models.Model):
employee_id = models.ForeignKey(Employees)
task_id = models.ForeignKey(Tasks)
date_from = models.DateTimeField()
date_to = models.DateTimeField()
def __str__(self):
return self.id
def get_absolute_url(self):
return reverse('records')
forms.py
class CreateRecordForm(forms.ModelForm):
employee_id = forms.ModelChoiceField(queryset=Records.objects.all().values('employee_id'))
task_id = forms.ModelChoiceField(queryset=Records.objects.all().values('task_id'))
date_from = forms.DateTimeField() #doesnt matter at the moment
class Meta:
model = Records
fields = ('employee_id', 'task_id', 'date_from')
views.py
class RecordCreateView(CreateView):
form_class = CreateRecordForm
template_name = 'record_new.html'
model = Records
#fields = ['employee_id', 'task_id', 'date_from']
Generic view below renders the drop-down selection correctly, so it is doable.
class RecordCreateView(CreateView):
template_name = 'record_new.html'
model = Records
fields = ['employee_id', 'task_id', 'date_from']
record_new.html
{% extends 'base.html' %}
{% block content %}
<h1>New record</h1>
<form action="" method="post">{% csrf_token %}
{{ form }}
<button class="btn btn-success ml-2" type="submit">save</button>
</form>
{% endblock content %}
Any help is greatly appreciated!

django data in form only appear after refresh

I am using custom user authentication for verifying user. I have table named voter and I am tacking username and password via from and matching that with username and password of table if it match user will be logged in and allowed them to pass to next page which contain form. In that form I initiated data but it will not appear automatically it will appear only when i refresh the page
code of my files is bellow (for some big file only relevant code is included that's why it is partial)
model.py (partial)
class Voter(models.Model):
serial_voter_id = models.AutoField(primary_key=True)
voter_id = models.CharField(unique=True, max_length=10)
voter_name = models.CharField(max_length=255)
voter_constituency = models.ForeignKey(Constituency, models.DO_NOTHING, blank=True, null=True)
username = models.CharField(unique=True, max_length=32)
password = models.TextField()
voter_address = models.CharField(max_length=255, blank=True, null=True)
area = models.CharField(max_length=10, blank=True, null=True)
city = models.CharField(max_length=10, blank=True, null=True)
pincode = models.IntegerField(blank=True, null=True)
adhar_no = models.BigIntegerField(unique=True)
birth_date = models.DateField()
age = models.IntegerField()
fingerprint = models.TextField(blank=True, null=True)
authenticity = models.CharField(max_length=3, blank=True, null=True)
wallet_id = models.TextField()
class Meta:
managed = False
db_table = 'voter'
forms.py
from django import forms
from .models import Voter
class VoterForm(forms.ModelForm):
class Meta:
model = Voter
fields = [
'serial_voter_id',
'voter_id',
'voter_name',
'voter_constituency',
'username',
'voter_address',
'area',
'city',
'pincode',
'adhar_no',
'birth_date',
'age',
'authenticity',
'wallet_id'
]
views.py (partial)
from .models import Voter
from .forms import VoterForm
def voter_login(request, *args, **kwargs):
contex = {}
return render(request, "poll/voter_login.html", contex)
def voter_verification(request, *args, **kwargs):
f_username = request.POST.get('username')
voter = Voter.objects.get(voter_id=1) # thing need to be dynamic hear by replacing it with username
f_username = request.POST.get('username')
f_password = request.POST.get('password')
u_password = voter.password # fetching the password from voter object
u_password = u_password.decode() # decoding binary password to string
form = VoterForm(request.POST or None, instance=voter)
if form.is_valid():
form.save()
form = VoterForm()
contex = {
'voter' : voter,
'f_username' : f_username,
'f_password' : f_password,
'u_password' : u_password,
'form' : form
}
# compare hear username and password entered by user and from database if these are correcgt then allow this view or redirect to voter_login view
if voter.username == f_username and u_password == f_password:
return render(request, "poll/voter_verification.html", contex)
else:
return render(request, "poll/voter_login.html", {})
voter_login.html
{% extends 'header.html' %}
{% block content %}
<table>
<form method="get" action='voter_verification'> {% csrf_token %}
username <input type="text" name="username">
password <input type="password" name="password">
<input type="submit" name="login" value="login">
</form>
{% endblock %}
voter_verification.html (template file)
<!DOCTYPE html>
<html>
<body>
{% if f_username == voter.username and f_password == u_password %}
<h1>verified</h1>
{% else %}
<h1>wrong id and password</h1>
{% endif %}
<form method='post' action='vote_page'> {% csrf_token %}
{{ form.as_p }}
<input type='submit' value="sumbit">
</form>
</body>
</html>
changes query in view model ( def voter_verification(request, *args, **kwargs):)
def voter_verification(request, *args, **kwargs):
f_username = request.POST.get('username')
voter = Voter.objects.get(username=f_username)
then request user check in voter table which have exits with same user name.
Thanks to DrMaxwellEdison from reddit for providing answer
https://www.reddit.com/r/djangolearning/comments/fecn1f/question_django_data_in_form_only_appear_after/
Please do not have a separate model that stores usernames and passwords aside from your User model. You can simply add a OneToOneField to the User model to connect this Voter model to the authenticated User, and you don't need to do any extra data storage (plus, you are more likely to be handling the password information incorrectly, exposing it to being compromised if your site is breached).
Also per your comment on SO, the POST is not working because of CSRF protection (the traceback of your error would likely have indicated this already). Please see those docs for details on how to proceed (hint: do not disable CSRF!).

Identifying & modifying single field in Django Model

I'm using Django to build a small system to control the lending and borrowing of some stuff our Students Café lend to students.
I'm having trouble identifying an object after a form submit, I want to mark the object as 'unaivalable' (disponible means available, so I want to set it to False) so next time someone comes to ask for THAT object, it will not show up in the 'lending' form.
All I need is a hint on how to achieve it, I've been looking through Django docs, and this site, with no success. Thanks in advance for the tips!
models.py
class Mate(models.Model):
color = models.CharField(max_length=2,
choices=COLOR_CHOICES, default=u'RO')
disponible = models.BooleanField(default=True)
def __unicode__(self):
return self.color
class Prestamo(models.Model):
cliente = models.ForeignKey(Usuario, null=False, blank=False)
mate = models.ForeignKey(Mate, null=False, blank=False)
termo = models.ForeignKey(Termo, null=False, blank=False)
bombilla = models.ForeignKey(Bombilla, null=False, blank=False)
fecha = models.DateTimeField(null=False, blank=False)
devuelto = models.BooleanField(default=False)
fecha_devolucion = models.DateTimeField(null=True, blank=True)
def __unicode__(self):
return str(self.pk)
views.py
#login_required
# Add_prestamo means 'Add lending' this basically deals with prestamo model, but i want to alter 'mate' objects here too.
def add_prestamo(request):
if request.method == 'POST':
form = PrestamoForm(request.POST,
auto_id=False, error_class=DivErrorList)
if form.is_valid():
prestamo = form.save(commit=False)
if request.POST.get('usuarios'):
miuser = request.POST.get('usuarios', '')
else:
miuser = ''
prestamo.cliente = Usuario.objects.get(nombre__exact=miuser)
# I KINDA NEED SOMETHING RIGHT HERE
prestamo.fecha = timezone.now()
prestamo.devuelto = False
prestamo.save()
return HttpResponseRedirect(reverse('list-prestamos'))
else:
form = PrestamoForm()
return TemplateResponse(request,
'gester/add_prestamo.html', {'form': form, })
add_prestamo.html
<form action="" method="post">
{% csrf_token %}
<table>
<tr>
<td>
<div class="ui-widget">
<label for="usuarios">Usuario: </label></td><td>
<input id="usuarios" name="usuarios">
</div>
</td>
</tr>
{{ form.as_table }}
</table>
<input class="btn" type="submit" value="Crear" />
</form>
In the template I show the form with a {{ form.as_table }} it display a select, but many of them (mates) have the same color, so when I get through POST in my view, how do I identify the exact object to alter the 'disponible' field value?
I really don't understand your codes but because you mention disponible, I hope this is what you mean.
prestamo.fecha = timezone.now()
prestamo.devuelto = False
//Because Prestamo model has a foreignkey for Mate model.
//The Mate model contains the disponible field which you want to access
// (to set it to False or unavailable)?
//This is how to access and update it.
prestamo.mate.disponible = False
prestamo.mate.save()
prestamo.save()