I want to edit my product details Django - django

I am trying to edit the details I gathered using a form with POST method now I want to edit those details. I tried it but it is not working can you guys tell what am I doing wrong ?
View of edit post
#login_required()
def edit_product(request, product_id):
form = NewPro()
edit = get_object_or_404(Product, product_id)
if request.method == 'POST':
form = NewPro(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('product')
else:
form = NewPro()
return render(request, "default/edit.html", {'form': form, 'edit': edit})
Url pattern
path('<int:product_id>/edit_product', views.edit_product, name='edit_product')
Html where I am trying to add the button
{% extends 'default/dashboard.html' %}
{% block content %}
<h1>Products Details </h1>
<p>These are the details of your product, {{ user.username }}</p>
<ul>
<li>{{ product_details.name }}</li>
<li>{{ product_details.price }}</li>
<li>{{ product_details.category }}</li>
<li>{{ product_details.store }}</li>
<li>{{ product_details.user }}</li>
</ul>
<a href={% url 'edit_product' edit.id %}>
<button>Edit Product</button>
</a>
{% endblock %}
Html where I am trying to show the form
{% extends 'default/dashboard.html' %}
<html>
<head><title>E-Commerce App</title></head>
{% block content %}
<h2>Edit Product</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">submit</button>
</form>
{% endblock %}
</html>
I want to used this card instead of the one you gave me.
<div class="card-deck">
<div class="card">
<img class="card-img-top" src=".../100px200/" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
<div class="card">
<img class="card-img-top" src=".../100px200/" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This card has supporting text below as a natural lead-in to additional content.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
<div class="card">
<img class="card-img-top" src=".../100px200/" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
</div>

You have to pass the instance of the product you want to edit to your form.
#login_required()
def edit_product(request, product_id):
product_to_edit = get_object_or_404(Product, pk=product_id)
form = NewPro(instance=product_to_edit)
if request.method == 'POST':
form = NewPro(request.POST, request.FILES, instance=product_to_edit)
if form.is_valid():
form.save()
return redirect('product')
else:
form = NewPro(instance=product_to_edit)
return render(request, "default/edit.html", {'form': form, 'product': product_to_edit})
On the comments you asked how to display all products inside cards so that there are 4 products per row. Try this out!
<div class="container">
<div class="row">
{% for product in products %}
<div class="col-sm-3">
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="..." alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{ product.title }}</h5>
<p class="card-text">{{ product.description }}</p>
Edit Product
</div>
</div>
</div>
{% endfor %}
</div>
</div>
For the issue you raise about using a card deck instead, This is how I would do it.
Please Note: I haven't tested it.
views.py:
def all_products(request):
products = Product.objects.all()
grouped_products = []
temp = []
for i in range(len(products)):
if (i+1) % 3 == 0:
grouped_products.append(temp)
temp = []
temp.append(products[i])
return render(request, 'products.html', {'products': grouped_products})
templates:
<div class="container">
{% for product_list in products %}
<div class="row">
<div class="card-deck">
{% for product in product_list %}
<div class="card">
<img class="card-img-top" src=".../100px200/" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
</div>

Related

why link is not working in html and how to solve it?

When i click a 'add to cart' button, it shows a blank page instead of cart page.
product.html
<a class="btn btn-secondary" href="{% url 'cart:add_cart' product.id %}">Add to Cart</a>
cart.views
def add_cart(request, product_id):
product = Product.objects.get(id=product_id)
try:
cart = Cart.objects.get(cart_id=_cart_id(request))
except Cart.DoesNotExist:
cart = Cart.objects.create(cart_id=_cart_id(request))
cart.save()
try:
cart_item = CartItem.objects.get(product=product, cart=cart)
if cart_item.quantity < cart_item.product.stock:
cart_item.quantity += 1
cart_item.save()
except CartItem.DoesNotExist:
cart_item = CartItem.objects.create(
product=product,
quantity=1,
cart=cart
)
cart_item.save()
return redirect('cart:cart_detail')
Your URL is probably not concatenated correctly. Try to debug your URL that should be in the "href" attribute, and you will see that there is probably some mistake.
In your main.urls, just add namespace in cart include.
let's add:
main.urls:
path('cart/',include('cart.urls',namespace='cart')),
OR
If above code doesn't work, try below code.
path('cart/',include(('cart.urls','url'),namespace='cart')),
And now this will work:
href="{% url 'cart:add_cart' product.id %}">
And see if it solves
this is the result when i click the button
product.html
{% extends 'base.html' %}
{% load static %}
{% block metadescription %}
{{ product.description|truncatewords:155 }}
{% endblock %}
{% block title %}
{% if category %}
{{ product.name }} -A&A store
{% endif %}
{% endblock %}
{% block content %}
<div class="row my_prod_row_class"
<div class="mx_auto">
<p>Home|{{product.category}}|{{product.name}}</p>
</div>
<div class="container">
<br>
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6 text-center ">
<div style="min-width:18rem">
<img src="{{product.image.url}}" alt="{{product.name}}">
</div>
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<div>
<h1 class="my_prod_title">{{product.name}}</h1>
<p>{{product.price}}$</p>
<p class="my_title">product Description </p>
<p class="text-justify my_prod_text">{{product.description}}</p>
{% if product.stock <= 0 %}
<p class="text-justify my_prod_text"><b>Out of stock </b></p>
{% else %}
<a class="btn btn-secondary" href="{% url 'cart:add_cart' product.id %}">Add to Cart</a>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}

Turbo-flask turbo.push when button is submitted

I am using WTForms and turbo-flask
I have a template which I want to change
<div>
{% if data is defined %}
{% for item in data %}
<div id="load" class="col-12 col-sm-6 offset-md-0 col-md-6 col-lg-4 col-xl-3 p-1 p-md-2">
<div class="card rounded p-1 d-flex flex-column h-100">
<div class="card-body p-1">
<h5 class="card-title">{{item._source.judgment_name}}</h5>
<h6 class="card-subtitle mb-2 text-muted">{{item._source.justice_kind_name}}</h6>
<p class="card-text">{{item._source.court_name}}</p>
<p class="card-text">{{item._source.adjudication_date}}</p>
{{item._id}}
{{item._source.cause_num}}
</div>
</div>
</div>
{% endfor %}
{% endif %}
</div>
And where I include it
<div class="container">
<div class="row px-2 pt-0">
{% include "test.html" %}
</div>
</div>
#app.route('/', methods=['GET', 'POST'])
def main():
form = SearchForm()
if form.is_submitted():
resp = es.search(index="test", query={"match_all": {}})
data = resp['hits']['hits']
turbo.push(turbo.replace(render_template("test.html", data=data), 'load'))
else:
return render_template('home.html', form=form)
When I use this script it doesn't want to work. Do you have any idea how to fix it?
I solved this. Here working code
in app.route function
if turbo.can_stream():
return turbo.stream(
turbo.replace(render_template('doc_cards.html', data=data), target='load_cards'))
else:
return render_template('home.html', form=search_form, data=data)
On page where content will be updated
<div class="container">
{% with data=data %}
{% include "doc_cards.html"%}
{% endwith %}
</div>
and dynamic content
<div id="load_cards" class="container">
{% if data is defined %}
{% for item in data %}
.......
{% endfor %}
{% endif %}
</div>

i am unable to pass data from view.py to html templates django

My name is arslan chaudhry, currently i am working with django. In my django project i have made some filters to filter the product category wise.i have successfully display the category of products. But when i click on the category image i recived an empity page no error is dispalyed.
I think data are not passing from view.py to html template.How i can fix this?
the code is given below.
views.py
def collectionsview(request, slug):
if(Category.objects.filter(slug=slug, status=0)):
products=Product.objects.filter(category__slug=slug)
category_name=Category.objects.filter(slug=slug).first()
contex={products:"products",category_name:"category_name"}
print(products)
return render(request, "store/product/index.html", contex)
else:
return HttpResponse('This is not a valid product')
html template
{% extends 'store/layouts/main.html' %}
{% block title %}Home{% endblock title %}
{% block body %}
<div class="container mt-3">
<div class="row">
<div class="col-md-12">
<h4>{{category_name}}</h4>
<div class="row">
{% for item in products %}
<div class="col-md-2">
<div class="card">
<a href="#">
<div class="card-body ">
<div class="card-image">
<img src="{{item.imge.url}}" alt="" width="100%" height="100%">
<h4 class="text-center mt-1" style="font-size: medium; font-weight: 600;">{{item.name}}</h4>
</div>
<span>{{item.original_price}}</span>
<span>{{item.selling_price}}</span>
</div>
</a>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock body %}

Image ids apparently not being created

I have created a template for displaying a photo gallery and giving users the ability to add photos to that gallery:
{% extends 'nowandthen/base.html' %}
{% block body_block %}
<br>
<br>
{% if pictures %}
<ul>
{% for p in pictures %}
<div class="container">
<div class="row">
<div class="col-md-8 card mb-4 mt-3 ">
<!-- Card -->
<!-- Card content -->
<div class="card-body d-flex flex-row">
<!-- Content -->
<div>
<!-- Title -->
<h4 class="card-title font-weight-bold mb-2">{{ p.title }}</h4>
<!-- Subtitle -->
<p class="card-text"><i class="far fa-clock pr-2"></i>{{ p.when_added }}</p>
</div>
</div>
<!-- Card image -->
<div class="view overlay">
<img class="card-img-top rounded-0" src="{{ p.image.url }}" alt="Card image cap">
<a href="#!">
<div class="mask rgba-white-slight"></div>
</a>
</div>
<!-- Card content -->
<div class="card-body">
<div class="collapse-content">
<!-- Text -->
<p class="card-text collapse" id="collapseContent">{{ p.description }}</p>
<!-- Button -->
<a class="btn btn-flat red-text p-1 my-1 mr-0 mml-1 collapsed" data-toggle="collapse" href="#collapseContent" aria-expanded="false" aria-controls="collapseContent">Click for description</a>
<i class="fas fa-share-alt text-muted float-right p-1 my-1" data-toggle="tooltip" data-placement="top" title="Share this post"></i>
<i class="fas fa-heart text-muted float-right p-1 my-1 mr-3" data-toggle="tooltip" data-placement="top" title="I like it"></i>
</div>
</div>
<div class="card-body">
<!-- comments -->
<h2>comments</h2>
{% if not p.comments %}
No comments
{% endif %}
{% for x in p.comment %}
<div class="comments" style="padding: 10px;">
<p class="font-weight-bold">
<h4>Comment by</h4> {{ x.user }}
<span class=" text-muted font-weight-normal">
{{ x.created_on }}
</span>
</p>
{{ x.body | linebreaks }}
</div>
{% endfor %}
</div>
<div class="card-body">
{% if new_comment %}
<h2>Your comment has been posted.</h2>
{% else %}
<h3>Leave a comment</h3>
<form action="{% url 'nowandthen:add_comment' p.image_id %}" method="POST">
{{ comment_form.as_p }}
{% csrf_token %}
<button type="submit" class="btn btn-primary btn-lg">Submit</button>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Card -->
{% endfor %}
</ul>
{% else %}
<li><strong>There are no photographs present.</strong></li>
{% endif %}
{% endblock %}
The idea is that there is an image associated with each comment - there is a for loop of {% for p in pictures %} at the start of the page, and I use variations of p. (e.g. p.image_id) to associate particular pictures with particular comments.
In addition, the urls.py contains the following:
path('add_comment/<int:p.image_id>', views.add_comment, name='add_comment')
However, when I run the code, I get an error message that suggests that image ids aren't being created (even though image is a field in he Pictures model I created):
Reverse for 'add_comment' with arguments '('',)' not found. 1 pattern(s) tried: ['add_comment/$']
What do you suggest, please?
EDIT: This is my view:
#login_required
def add_comment(request, image_id):
new_comment = None
template_name = 'add_comment.html'
image = get_object_or_404(Picture, id=image_id)
comment = image.comments.filter(active=True)
new_comment = None
# Comment posted
if request.method == 'POST':
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
# Create Comment object and don't save to database yet
new_comment = comment_form.save(commit=False)
# Assign the current post to the comment
new_comment.post = post
# Save the comment to the database
new_comment.save()
else:
comment_form = CommentForm()
context = {'image': image,'comment': comment, 'new_comment': new_comment,'comment_form': comment_form}
return render(request, template_name, context)
And this is my add_comment.html template:
{% extends 'nowandthen/base.html' %}
{% load staticfiles %}
{% block title_block %}
Add self
{% endblock %}
{% block body_block %}
<h1>Add a Comment</h1>
<div>
<form id="comment_form" method="post" action="{% url 'nowandthen:add_comment' comment_id%}" enctype="multipart/form-data" >
{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="submit" value="Add Comment" />
</form>
</div>
{% endblock %}
Since you pictures variable is a Queryset, when you loop through it in your template, to access its ID, you just need to do it that way. instance.id
Based on your case, you will have:
{% url 'nowandthen:add_comment' p.id %}
And you will be able to access the id in your view with image_id

Have the first article from a model at the top displayed

I am creating a Django blog app and I was wondering if it was possible to have the first blog post as pictured in this design.
What I have done so far is that I have been able to get the bottom three articles but I have been confused on how to approach the top post.
This is my template code so far:
<div class="row">
<!-- Blog Entries Column -->
{% for article in articles %}
<div class="col-lg-4 mt-4 ">
<div class="card mb-4">
<div class="card-body">
<h2 class="card-title">{{ article.title }}</h2>
<p class="card-text text-muted h6"> <img class="image-size radius-of_image" src="article/{{ article.upload_image }}"> | {{ article.author }} | {{ article.created_on | date}} </p>
<p class="card-text">{{article.content|slice:":200" }}</p>
Read More →
</div>
</div>
{% if forloop.counter|divisibleby:"3" and not forloop.last %}
<div class="row">
{% endif %}
</div>
{% endfor %}
</div>
</div>
This is how my views look like
def home(request):
if request.method == 'GET':
queryset = Post.objects.filter(status=1).order_by('-created_on')
articles = {
"articles": queryset
}
return render(request, 'home.htm', articles)
django has several template filters which are easy to use and avoid headache of developers. You can use {{ value|first }} to display the first model instance in your template from your query set