Field 'id' expected a number but got '9dzlzyftu9k5fi5ta8omk1mxgx1lyvhg' - python

It works fine until the form is created, but if i enter a value and click the Submit button, the following error code is displayed. The long string of the error code is cart_id. How can I change it? This is a simulated payment system that receives a cart with products and makes a payment.
models.py
class Cart(models.Model):
cart_id = models.CharField(max_length=250, blank=True)
customer = models.ForeignKey(User, on_delete=models.CASCADE)
date_added = models.DateField(auto_now_add=True)
class Meta:
db_table = 'Cart'
ordering=['date_added']
def __str__(self):
return self.cart_id
class Payment(models.Model):
cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
card_number = models.IntegerField()
validity = models.IntegerField()
cvc = models.IntegerField()
card_password = models.IntegerField()
def __str__(self):
return '{0} {1}'.format(self.cart, self.card_number)
urls.py
urlpatterns = [
path('add/<int:pk>/', views.add_cart, name='add_cart'),
path('', views.cart_detail, name='cart_detail'),
path('remove/<int:pk>/', views.cart_remove, name='cart_remove'),
path('full_remove/<int:pk>/', views.full_remove, name='full_remove'),
path('payment_charge/', views.payment_charge, name='payment_charge'),
]
view.py
def _cart_id(request):
cart = request.session.session_key
if not cart:
cart = request.session.create()
return cart
def payment_charge(request):
if request.method == "POST":
form = PaymentForm(request.POST, request.FILES)
if form.is_valid():
post = form.save(commit=False)
post.cart_id = _cart_id(request)
post.save()
return redirect('cart:cart_detail')
else:
form = PaymentForm()
context = {
'form' : form
}
return render(request, 'cart/payment_form.html', context)
forms.py
class PaymentForm(forms.ModelForm):
class Meta:
model = Payment
fields = ('card_number','validity','cvc','card_password')
base.html
<div class="mx-auto">
<a href="{% url 'cart:payment_charge' %}" type="button"
class="btn btn-outline-dark my_custom_button">
Continue Shopping
</a>
</div>
payment_form.html
<form action="" method="POST">
{% csrf_token %}
<table>
{{form.as_table}}
</table>
<input type="submit" value="제출">
</form>

Related

Django, why this is not working(reply of comment function)

I want to make reply of comment function. so I added parent option in Answer model. answer_create() working well.
but, when i submit reply of comment, url is different with url i setting.
i think i should be http://127.0.0.1:8000/debateboard/305/
but return http://127.0.0.1:8000/debateboard/answer/reply/31/
help me plz
models.py
class Question(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='author_question')
subject = models.CharField(max_length=200)
content = models.TextField()
create_date = models.DateTimeField()
modify_date = models.DateTimeField(null=True, blank=True)
voter = models.ManyToManyField(User, related_name='voter_question')
def __str__(self):
return self.subject
class Answer(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='author_answer')
question = models.ForeignKey(Question, on_delete=models.CASCADE)
content = models.TextField()
create_date = models.DateTimeField()
modify_date = models.DateTimeField(null=True, blank=True)
voter = models.ManyToManyField(User, related_name='voter_answer')
######### i added this parent to make reply of comment
parent = models.ForeignKey('self', on_delete=models.CASCADE, blank=True, null=True, related_name='+')
def __str__(self):
return self.content
#property
def children(self):
return Answer.objects.filter(parent=self).order_by('-create_date').all()
#property
def if_parent(self):
if self.parent is None:
return True
return False
urls.py
urlpatterns = [
path('', base_views.index, name = 'index'),
path('<int:question_id>/', base_views.detail, name = 'detail'),
path('answer/create/<int:question_id>/', answer_views.answer_create, name = 'answer_create'),
path('answer/reply/<int:answer_id>/', answer_views.reply_comment_create , name='reply_comment_create'),
view
def detail(request, question_id):
# question = Question.objects.get(id = question_id)
question = get_object_or_404(Question, pk = question_id)
context = {'question' : question}
return render(request, 'debateboard/detail.html', context)
#login_required(login_url='common:login')
def reply_comment_create(request, answer_id):
answer = get_object_or_404(Answer, pk=answer_id)
# question = get_object_or_404(Question, pk = answer.question.id)
if request.method == "POST":
form = AnswerForm(request.POST)
if form.is_valid():
sub_answer = form.save(commit=False)
sub_answer.author = request.user
sub_answer.create_date = timezone.now()
sub_answer.parent = answer.id
sub_answer.save()
# return redirect('{}#answer_{}'.format(resolve_url('debateboard:detail', question_id = answer.question.id), answer.id))
return redirect('debateboard:detail', question_id = answer.question.id)
else:
return HttpResponseNotAllowed('only post is possible')
context = {'question' : answer.question, 'form': form}
return render(request, 'debateboard/detail.html', context)
#login_required(login_url = 'common:login')
def answer_create(request, question_id):
question = get_object_or_404(Question, pk = question_id)
# question.answer_set.create(content=request.POST.get('content'), create_date = timezone.now())
if request.method == 'POST':
form = AnswerForm(request.POST)
if form.is_valid():
answer = form.save(commit=False)
answer.author = request.user
answer.create_date = timezone.now()
answer.question = question
answer.save()
# return redirect('debateboard:detail', question_id = question.id)
return redirect('{}#answer_{}'.format(resolve_url('debateboard:detail', question_id = question.id), answer.id))
else:
return HttpResponseNotAllowed('Only POST is possible.')
context = {'question': question, 'form': form}
return render(request, 'debateboard/detail.html', context)
html
<!-- for reply of comment -->
<form action="{% url 'debateboard:reply_comment_create' answer.id %}" method="POST">
{% csrf_token %}
<div class="form-group">
<textarea name="reply_comment_{{ answer.id }}" id="reply_comment_{{ answer.id }}" cols="20" rows="5"></textarea>
<button type="submit">dd</button>
</div>
</form>
<!-- for comment-->
<form action="{% url 'debateboard:answer_create' question.id %}" method="post">
{% csrf_token %}
<div class="form-group">
<textarea {% if not user.is_authenticated %}disabled placeholder="로그인후 이용가능" {% endif %} name="content" id="content" cols="30" rows="15"></textarea>
</div>
<input {% if not user.is_authenticated %}disabled placeholder="로그인후 이용가능" {% endif %} type="submit" class="btn btn-primary" value="답변등록">
</form>
The address is structured this way because you add an object of class Answer. Anyway, look at how your url is constructed.
path('answer/reply/<int:answer_id>/', answer_views.reply_comment_create , name='reply_comment_create'),
If you want, check the SlugField which can be useful for create custom url.

Django error : NoReverseMatch at /Post/8 Reverse for 'comments' with arguments '('',)' not found

I am working on my project I faced a problem with "COMMENT":
I add a comment as a section when the user clicks "view" button to see the post from the home page.
Django error :
NoReverseMatch at /Post/8
Reverse for 'comments' with arguments '('',)' not found. 1 pattern(s) tried: ['Post/(?P[0-9]+)$']
views.py file
def viewList(request, id):
item = Post.objects.get(id=id)
context = {
'item': item,
'comment_form': comment(),
'comments': item.get_comments.all(),
}
return render(request, 'auctions/item.html', context)
#login_required
def comments(request, id):
listing = Post.objects.get(id=id)
form = comment(request.PSOT)
newComment = form.save(commit=False)
newComment.user = request.user
newComment.listing = listing
newComment.save()
return HttpResponseRedirect(reverse("listing", {'id': id}))
models.py file
class Post(models.Model):
# data fields
title = models.CharField(max_length=64)
textarea = models.TextField()
# bid
price = models.FloatField(default=0)
currentBid = models.FloatField(blank=True, null=True)
imageurl = models.CharField(max_length=255, null=True, blank=True)
category = models.ForeignKey(
Category, on_delete=models.CASCADE, default="No Category Yet!", null=True, blank=True)
creator = models.ForeignKey(User, on_delete=models.PROTECT)
watchers = models.ManyToManyField(
User, blank=True, related_name='watched_list')
date = models.DateTimeField(auto_now_add=True)
# for activated the Category
activate = models.BooleanField(default=True)
def __str__(self):
return f"{self.title} | {self.textarea} | {self.date.strftime('%B %d %Y')}"
class Comment(models.Model):
body = models.CharField(max_length=100)
createdDate = models.DateTimeField(default=timezone.now)
# link to the post model
auction = models.ForeignKey(
Post, on_delete=models.CASCADE, related_name="get_comments")
user = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.BooleanField(default=True)
def __str__(self):
return self.createdDate.strftime('%B %d %Y')
HTML file
<!-- Comments -->
<div class="comments">
<p>Add a comment:</p>
<div class="row">
<div class="col-6">
<form action="{% url 'comments' listing.id %}" method="post">
{% csrf_token %}
<div class="input-group">
{{ comment_form }}
</div>
<input type="submit" value="save" class="btn btn-outline-dark btn-sm m-1"/>
</form>
</div>
{% for comment in comments %}
<div class="col-4">
Comments:
<h4>Name: {{comment.user}}</h4>
<h4>Content: {{comment.body}}</h4>
<h4>Date: {{comment.createdDate}}</h4>
</div>
{% endfor %}
</div>
</div>
url.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("register", views.register, name="register"),
path("category/", views.category, name="category"),
path("Post", views.createList, name="createList"),
#comment url
path("Post/<str:id>", views.viewList, name="viewList"),
path("Post/<int:id>", views.comments, name="comments"),
]
You passed the Post object as item to the template, hence you should resolve the URL with:
<!-- use item not listing &downarrow; -->
<form action="{% url 'comments' item.id %}" method="post">
…
</form>
Your view to create comments also has some mistakes: you should use request.POST, not request.PSOT:
from django.shortcuts import redirect
#login_required
def comments(request, id):
if request.method == 'POST'
form = comment(request.POST, request.FILES)
if form.is_valid():
form.instance.user = request.user
form.instance.auction_id = id
form.save()
return redirect('viewList', id=id)
Furthermore your comment form should inherit from ModelForm and not Form:
class comment(forms.ModelForm):
class Meta:
model = Comment
fields = ('content',)
widgets = {
'content': forms.Textarea(attrs={"class": "form-control"})
}
finally your urls.py has two (fully) overlapping patterns, you should use a different URL to add the given comment:
urlpatterns = [
# …
#comment url
path('Post/<int:id>', views.viewList, name='viewList'),
path('Post/<int:id>/add', views.comments, name='comments'),
]
Note: Usually a Form or a ModelForm ends with a …Form suffix,
to avoid collisions with the name of the model, and to make it clear that we are
working with a form. Therefore it might be better to use CommentForm instead of
comment.

Adding a Like button to Django Blog Project not working properly

In my Blog Django Project I am trying to create a Like Feature, but currently facing the below error:
Reverse for 'post-detail' with no arguments not found. 1 pattern(s) tried: ['blog/(?P<slug>[-a-zA-Z0-9_]+)/$']
What should I do to prevent this error and to return back to the same Post-detail page after pressing the like button?
Here is the urls.py
path('blog/<slug:slug>/', PostDetailView.as_view(), name='post-detail'),
path('blogs/like', like_post, name='like-post'),
Here is the models.py
class Post(models.Model):
liked = models.ManyToManyField(User, default=None, blank=True, related_name='liked')
def num_likes(self):
return self.liked.all().count()
def get_absolute_url(self):
return reverse('blog:post-detail', kwargs={'slug': self.slug})
LIKE_CHOICES = (
('Like', 'Like'),
('Unlike', 'Unlike')
)
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
value = models.CharField(choices=LIKE_CHOICES, default='Like', max_length=10)
date_liked = models.DateTimeField(default=timezone.now)
def __str__(self):
return str(self.post)
Here is the views:
I have made a couple of trials but did not work, I have commented them in the end of the views.py as they returned like_post() missing 1 required positional argument: 'slug'
class PostListView(ListView):
model = Post
template_name = "blog/post_list.html" # <app>/<model>_<viewtype>.html
ordering = ['-date_posted']
context_object_name = 'posts'
paginate_by = 1
class PostDetailView(DetailView):
model = Post
template_name = "blog/post_detail.html" # <app>/<model>_<viewtype>.html
def get(self, request, *args, **kwargs):
res = super().get(request, *args, **kwargs)
self.object.incrementViewCount()
return res
def like_post(request):
user=request.user
if request.method=='POST':
post_id=request.POST.get('post_id')
post_obj= Post.objects.get(id=post_id)
if user in post_obj.liked.all():
post_obj.liked.remove(user)
else:
post_obj.liked.add(user)
like,created=Like.objects.get_or_create(user=user,post_id=post_id)
if not created:
if like.value=='Like':
like.value='Unlike'
else:
like.value='Like'
like.save()
return redirect('blog:post-detail') <------------ Error Showing from Here
#post = get_object_or_404(Post, slug=Post.slug)
#if post.slug != slug:
#return redirect('blog:post-detail', slug=Post.slug)
Here is the template:
<form action="{% url 'blog:like-post' %}" method="POST">
{% csrf_token %}
<input type="hidden" name="post_id" value='{{post.id}}'>
{% if user not in obj.liked.all %}
<button class="ui button positive" type="submit"> Like</button>
{% else %}
<button class="ui button negative" type="submit">Unlike</button>
{% endif %}
<br>
<strong>{{ post.liked.all.count }} Likes</strong>
</form>
redirect('blog:post-detail', slug=post_obj.slug)

Django how make a filter of foreignkey based on parent foreignkey selected in other form?

I'm trying to create a form for edit table Person, but in this form field Car must be filtered by selected Company. I'm very new to python/django so this may be a bad approach, high level suggestions welcome. Here is what I have:
I have 3 models in models.py:
from django.db import models
class Company(models.Model):
company = models.CharField(max_length=25)
def __str__(self):
return self.company
class Car(models.Model):
car = models.CharField(max_length=25)
company = models.ForeignKey(Company, on_delete = models.CASCADE)
def __str__(self):
return self.car
class Person(models.Model):
name = models.CharField(max_length=20)
car = models.ForeignKey(Car, on_delete = models.CASCADE)
def __str__(self):
return self.name
views.py:
def index(request):
people = Person.objects.all().select_related('car__company')
table = PersonTable(people)
return render(request, 'index.html', {'table': table})
def edit(request, id):
person = Person.objects.get(id = id)
car = Car.objects.get(id = person.car_id)
company = Company.objects.get(id = car.company_id)
if request.method == 'POST':
form = PersonForm(car.company_id, request.POST, instance=person)
if form.is_valid():
form.save()
return redirect('/person/')
else:
companys = CompanyForm(instance=company)
form = PersonForm(car.company_id, instance=person)
return render(request, 'person/edit.html', {'companys':companys, 'form':form})
def Company_select(request):
if request.method == 'POST':
form = CompanySelectForm(request.POST)
if form.is_valid:
return redirect('/person/edit/1/') # Return to form PersonForm with id=1.
# How to return selected Company?
# How to return to page with other id?
else:
form = CompanySelectForm()
return render(request, 'person/company_select.html', {'form':form})
urls.py:
app_name = 'person'
urlpatterns = [
path('edit/<int:id>/', views.edit),
path('company/', views.Company_select, name='company'),
path('', views.index),
]
forms.py
class CompanyForm(forms.ModelForm):
class Meta:
model = Company
fields = ('company',)
class CompanySelectForm(forms.Form):
company = forms.ModelChoiceField(queryset=Company.objects.all().order_by('company'))
class Meta:
fields = ('company',)
class PersonForm(forms.ModelForm):
class Meta:
model = Person
fields = ('name', 'car',)
def __init__(self, company, *args, **kwargs):
super(PersonForm, self).__init__(*args, **kwargs)
self.fields['car'].queryset = Car.objects.filter(company=company) #Filter by Company
edit.html
{% extends "base.html" %}
{% block header %}Edit{% endblock header %}
{% block content%}
<form action="" method="post">
{% csrf_token %}
{{ form.as_table }}
{{ companys.as_table }}
<button type="button" class="btn btn-default btn-xs">Select Company</button>
<button class="btn btn-primary" type="submit" name="submit">submit</button>
</form>
{% endblock content %}
company_select.html
{% extends "base.html" %}
{% block header %}Select Company{% endblock header %}
{% block content%}
<form action="" method="post">
{% csrf_token %}
{{ form.as_table }}
<button class="btn btn-primary" type="submit" name="submit">submit</button>
</form>
{% endblock content %}
This is my proposition : tested
form.py => add attribut that will call a JS function defined in your .html
class PersonForm(ModelForm):
class Meta:
model = Person
fields = ('name', 'company', 'car')
def __init__(self, *args, **kwargs,):
super(PersonForm, self).__init__(*args, **kwargs)
class SelectForm(Form):
name = CharField(label='name')
company = ChoiceField(label='company')
car = ChoiceField(label='car')
class Meta:
fields = ('name', 'company', 'car', )
def __init__(self, cars=None, *args, **kwargs, ):
super(SelectForm, self).__init__(*args, **kwargs)
self.fields['car'].choices = cars
self.fields['company'].choices = tuple(Company.objects.all().values_list(flat=False))
self.fields['company'].widget.attrs['onchange'] = "load_car()"
edit.html: => define the JS function
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form id='myform' method="POST">
{% csrf_token %}
{{ form }}
</form>
<button class="btn btn-primary" type="submit" name="submit">submit</button>
</body>
<script>
function load_car()
{
document.getElementById('myform').action = "/stack/myview";
document.getElementById("myform").submit();
}
</script>
</html>
Views.py:=> new view that will look for the company name in the database and return to the template
def index(request): # RF configuration FORM
form = PersonForm()
content = {'form': form}
return render(request, 'stack/index.html', content)
def edit(request, my_id):
if request.method == 'POST':
form = PersonForm(request.POST)
if form.is_valid():
form.save()
# Do ....
return HttpResponseRedirect(reverse('stack:index'))
else:
person = Person.objects.values_list().get(id__exact=my_id)
cars = []
[cars.append((x['car'], x['car'])) for x in
list(Car.objects.filter(company__exact=person[2]).values('car'))]
form = SelectForm(cars=cars, initial={'name': person[1], 'company': person[2], 'car': person[3]})
content = {'form': form}
return render(request, 'stack/edit.html', content)
else:
person = Person.objects.values_list().get(id__exact=my_id)
cars = []
[cars.append((x['car'], x['car'])) for x in list(Car.objects.filter(company__exact=person[2]).values('car'))]
form = SelectForm(cars=cars, initial={'name': person[1], 'company': person[2], 'car': person[3]})
content = {'form': form}
return render(request, 'stack/edit.html', content)
def myview(request):
cars = []
[cars.append((x['car'], x['car'])) for x in list(Car.objects.filter(company__exact=request.POST['company']).
values('car'))]
form = SelectForm(cars=cars, initial={'name': request.POST['name'], 'company': request.POST['company'], 'car': None})
content = {'form': form}
return render(request, 'stack/edit.html', content)
I install django-smart-selects
In models.py:
from smart_selects.db_fields import ChainedForeignKey
...
class Person(models.Model):
name = models.CharField(max_length=20)
company = models.ForeignKey(Company, on_delete = models.CASCADE)
car = ChainedForeignKey(
Car,
chained_field="company",
chained_model_field="company",
show_all=False,
auto_choose=True,
sort=True,
on_delete=models.CASCADE,
blank=True,
null=True)
def __str__(self):
return self.name

How do i limit the numbers if comment to be displayed

I have multiple comments on my homepage, how do i limit the comment to be displayed on a post. Like, i have 10 comments and i want to display only 2 comments.
class Image(models.Model):
imageuploader_profile = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE, null=True, blank=True)
first_upload_image = models.FileField(upload_to ='picmate',null=True, blank=True)
second_upload_image = models.FileField(upload_to ='picmate',null=True, blank=True)
image_caption = models.CharField(max_length=700)
date = models.DateTimeField(auto_now_add=True, null= True)
class Meta:
verbose_name = 'Image'
verbose_name_plural = 'Images'
ordering = ['-date']
def __str__(self):
return self.image_caption
class Comments (models.Model):
comment_post = models.TextField()
author = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE, null=True, blank=True)
commented_image = models.ForeignKey('Image', on_delete=models.CASCADE, related_name='comments')
date = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = 'Comment'
verbose_name_plural = 'Comments'
ordering = ['-date']
def __str__(self):
return self.author.__str__()
def home(request):
all_images = Image.objects.filter(imageuploader_profile=request.user.id)
users = User.objects.all()
next = request.GET.get('next')
if next: return redirect(next)
context = {
'all_images': all_images,
'users': users,
}
return render(request,'home.html', context,)
#login_required
def comments(request, id):
post = get_object_or_404(Image,id=id)
# current_user = request.user
print(post)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.author = request.user
comment.commented_image = post
comment.save()
return redirect('/')
else:
form = CommentForm()
all_comments = Comments.objects.filter(
author=request.user.id,
commented_image=post,
)
{% for comment in post.comments.all %}
<div class="mb-1" style="padding-bottom:-10px;position:relative;top:-10px">
<div class="truncate card-meta dark-grey-text" style="">
<a href="#" class="username dark-grey-text text-lowercase">
{{ comment.author }}</a> {{ comment.comment_post }}
</div>
</div>
{% endfor %}
You can use the django template tag slice
{% for comment in post.comments.all|slice:":2" %}
{{ comment.author }}
{% endfor %}

Categories

Resources