So here's my code first and foremost. I'm new to Django and trying to create an ecommerce site. The way it works is that the admin creates products and users come on to the site and purchase them. The site uses Stripe to process payments.
views.py:
from django.shortcuts import render
from django.views import generic
from django.core.paginator import Paginator
from django.conf import settings
import stripe
import decimal
stripe.api_key = settings.STRIPE_SECRET_KEY
from .models import Product
# Create your views here.
class ProductListView(generic.ListView):
model = Product
paginate_by = 3
def get_context_data(self, **kwargs): # new
context = super().get_context_data(**kwargs)
context['key'] = settings.STRIPE_PUBLISHABLE_KEY
return context
def charge(request):
if request.method == 'POST':
charge = stripe.Charge.create(
amount=round(decimal.Decimal(request.POST['price'])),
currency='usd',
description='A Django charge',
source=request.POST['stripeToken']
)
return render(request, 'store/charge.html')
product_list.html:
{% extends 'home/base_generic.html' %}
{% load static %}
{% load cool_paginate %}
{% block add %}
<link rel="stylesheet" href="{% static 'store/css/products.css'%}">
{% endblock %}
{% block title %} <title> Store </title> {% endblock %}
{% block content %}
<div class="row">
{% for product in product_list %}
<div class="col-sm-4">
<div class="card" id="django-card" style="width: 300px; height: 350px;">
<img class="card-img-top" src="{{ product.image.url }}" height=150px width=150px>
<div class="card-body">
<h5 class="card-title">{{ product.name }}</h5>
<p class="card-text">
{{ product.description }} And only {{ product.price }}!
</p>
<form action="{% url 'charge' %}" method="post">
{% csrf_token %}
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="{{ key }}"
data-description="A Django Charge"
data-amount= "{{ product.price_in_cents }}"
data-locale="auto">
</script>
<input type="hidden" name="price" value="{{ product.price_in_cents }}">
</form>
</div>
</div>
</div>
{% endfor %}
<div class="container-fluid">
<div style="margin-top: 50px;"> {% cool_paginate page_obj=product %}</div>
</div>
</div>
{% endblock %}
So, my question is, when the user selects a product to purchase, how do I tell the view to use that products price? The way I've been doing it is using a hidden html value field in the input. But this can't be secure. Thanks to all who take the time to respond.
Ok, after a few grueling hours of work I solved it. I opted to keep the hidden field form but instead of using price I used it to return the product primary key. Which I used in the view to grab the price and make charges.
Related
I'm creating a ecommerce store using django And tried s many things to do this.index page is working pretty well but I want select specific product when I click .ex: when I click a shoe I want to enter shoe detail page with shoe image and all the necessary details.Here is my home page.And also I highly recommend to check my all code because you can't get any idea with only this code.github source code here.thanks dinindu
{% extends 'store/main.html'%}
{% load static %}
{% block content %}
<style>
img:hover{
opacity: 0.5;
}
</style>
<div class="row">
{% for product in products %}
<div class="col-lg-4">
<a href="{% url 'productDetail' Product.name %}"><img
class="thumbnail" src="{{product.imageURL}}"></a>
<div class="box-element product">
<h6><strong>{{product.name}}</strong></h6>
<hr>
<button data-product="{{product.id}}" data-action="add"
class="btn btn-outline-secondary add-btn update-cart">Add to
Cart</button>
<h4 style="display: inline-block; float:
right"><strong>Rs {{product.price}}</strong></h4>
</div>
</div>
{% endfor %}
</div>
{% endblock content %}
you could do something like this, an adapt it to your project:
Views:
def product_list(request):
products = Product.objects.all()
return render(request,'list.html',{'products': products})
def product_detail(request, id):
product = Product.objects.get(id=id)
return render(request,'detail.html',{'product': product,})
urls:
path('products/', views.product_list, name='product_list'),
path('products/<int:id>/', views.product_detail, name='product_detail')
templates
list.html
{% for product in products %}
<div>
<a href="{% url 'product_detail' product.id %}">
<img src="{ product.image.url }}">
</a>
{{ product.name }}
</div>
{% endfor %}
detail.html
<div>
<img src="{{ product.image.url }}">
<h2>{{ product.name }}</h2>
<h3>{{ product.price }}</h3>
<h4>{{ product.digital }}</h4>
</div>
I am new to both ajax and django. I want to fetch phone number from database and want to display on template when click user the contact button. But in my case I am getting all the phone numbers in first button itself which is not correct. Because different persons have different phone numbers. Please help me. Thanks in advance.
views.py:
from django.shortcuts import render, redirect
from .models import listing_model
from .forms import listing_form
from django.http import HttpResponse
def submissions(request):
tasks = listing_model.objects.all()
form = listing_form()
if request.method =='POST':
form = listing_form(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('submissions')
context = {'tasks':tasks, 'form':form}
return render(request, 'submission.html', context)
#ajax
def contact(request):
numbers= listing_model.objects.values('phone')
return HttpResponse( numbers )
home.html
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %}Home{% endblock %}
{% block body %}
<div class="container">
<div class="row">
<form method="GET" class="mx-auto" ><br>
{{ user_filter.form }}<br><br>
<button type="submit" class="btn btn-info" style="margin-left:250px">Search</button>
</form>
</div>
</div>
<div> </div>
<div class="container">
<div class="row">
{% for task in tasks %}
<div class ="col-md-4">
<div class="card" style="width:300px">
<div class="card-body">
<h4 class="card-title">Title : {{ task.title }}</h4>
<div>Address : {{ task.address }}</div>
<div>City : {{ task.city }}</div>
<img src="{{ task.image.url }}" style="max-height:200px">
<div> </div>
<button class="btn btn-primary" id="request-btn">Contact</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#request-btn").click(function(e){
e.preventDefault();
$.ajax({
url: "/listings/contact",
type: "GET",
datatype:"json",
success: function(numbers){
alert(numbers)
}
});
});
});
</script>
</div>
</div></div>
{% endfor %}
</div></div>
{% endblock %}
urls.py
from django.contrib import admin
from django.urls import path
from ajax_with_djnago import views
urlpatterns = [
path('admin/', admin.site.urls),
path('listings/contact/<str:id>', views.contact),
path('', views.home)
]
views.py
from django.shortcuts import render
from .models import listing_model
from django.http import JsonResponse
def home(request):
all_detail = listing_model.objects.all()
print(all_detail)
return render(request, 'index.html', context={'tasks': all_detail})
# ajax
def contact(request, id):
numbers = listing_model.objects.get(id=id)
return JsonResponse({'numbers': numbers.phone}
)
models.py
from django.db import models
# Create your models here.
class listing_model(models.Model):
title = models.CharField(max_length=200, blank=True)
address = models.CharField(max_length=200)
city = models.CharField(max_length=200)
image = models.ImageField(upload_to='images', blank=True)
phone = models.IntegerField()
def __str__(self):
return self.title
index.html
<div class="container">
<div class="row">
{% for task in tasks %}
<div class="col-md-4">
<div class="card" style="width:300px">
<div class="card-body">
{% for task in tasks %}
<h4 class="card-title">Title : {{ task.title }}</h4>
<div>Address : {{ task.address }}</div>
<div>City : {{ task.city }}</div>
<div> </div>
<button class="btn btn-primary"
id={{ task.id }} onclick="showPopup('{{ task.id }}')">Contact
</button>
<p id="contact"></p>
{% endfor %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
function showPopup(id) {
$.ajax({
url: "/listings/contact/" + id,
method: 'GET',
headers: {'X-CSRFToken': '{{ csrf_token }}'},
success: function (data) {
$('#contact').html(data['numbers']);
}
});
}
</script>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
For Complete Code Please check this link
I have a problem I have a site which displays users but it displays users not in a straight line but in an inverted pyramid. It could be because I am using django-filter app but it shouldnt create a problem as such. The profiles right at the end (especially in the mobile view) overlap and drag. It gets worse as profiles increase. Is it possible to align the profiles or user list in a straight line?
Please find below my code.
filters.py(for djang-filters app)
import django_filters
from userprofile.models import UserProfiles
class UserProfilesFilter(django_filters.FilterSet):
class Meta:
model = UserProfiles
fields = ['gender', 'age', 'Nationality','preference', 'Country',
'City']
views.py
#login_required
def profiles_list(request):
filter = UserProfilesFilter(request.GET, queryset =
UserProfiles.objects.all().order_by('-pub_date'))
return render(request,"userprofile/user_list.html", {'filter': filter})
user_list.html
{% extends 'base.html' %}
{% block content %}
{% load static %}
{% load bootstrap %}
<div class="container">
<form class="form-horizontal col-md-4 col-lg-4 col-sm-4" action=""
method="get">
{{ filter.form|bootstrap}} {% csrf_token %}
<input type="submit" value='search'/>
</form>
{% for profile in filter.qs %}
<div class="col-md-12 col-lg-12 col-sm-12 col-xs-12">
<hr>
<a href="{% url 'userprofile:profileview' profile.user %}"><h3>{{
profile.user }}</h3></a>
<br>
<img src="{{ profile.image.url }}" class="rounded mx-auto d-block img-
responsive float-left" style= "max-height: 100px; max-width: 100px;">
<br><br>
<br><br> <br>
<div class="font-weight-normal text-justify">
Gender: {{ profile.gender }}
<br>
Country: {{ profile.Country }}
<br>
Description: {{ profile.summary }}
<br>
Preferences: {{ profile.preference }}
<br><br>
{% endfor %}
</div>
</div>
<!--adnow ad-->
<script type="text/javascript">
(sc_adv_out = window.sc_adv_out || []).push({
id : "575193",
domain : "n.ads1-adnow.com"
});
</script>
<script type="text/javascript" src="//st-n.ads1-adnow.com/js/a.js">
</script>
<div id="SC_TBlock_575193" class="SC_TBlock">loading...</div>
<!--adnow finishes-->
{% endblock %}
You should close your div tags in each for loop, since you start them within the loop.
Change:
{% endfor %}
</div>
</div>
to:
</div>
</div>
{% endfor %}
I am kinda new with the MVC and MTV concept and i am trying to learn Python Django. I want to make catalog with books, must have add and delete functionality. I am trying to follow best practices and working with Generic views, but kinda stuck at the end, i feel that i am missing something very small but i cant figure it out - to be honest i am very exhausted at this moment and i dont have much time. So this is my code:
Models:
class Books(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=200)
isbn = models.CharField(max_length=200)
pages = models.IntegerField(default=0)
def __unicode__(self):
return self.title
class BooksForm(ModelForm):
class Meta:
model = Books
Views:
# coding: utf-8
from django.core.urlresolvers import reverse_lazy
from django.views.generic import ListView, UpdateView, CreateView, DetailView
from models import Book
class BooksDetailView(DetailView):
model = Book
template_name = "books_portal/details.html"
class BooksCreateView(CreateView):
model = Book
template_name = "books_portal/add.html"
success_url = reverse_lazy('books_portal')
class BooksUpdateView(UpdateView):
model = Book
template_name = "books_portal/add.html"
success_url = reverse_lazy('books_portal')
class BooksListView(ListView):
model = Book
context_object_name = 'books_list'
template_name = "books_portal/index.html"
def get_queryset(self):
return Book.objects.order_by('author')[:5]
Templates:
add.html
{% extends "books_portal/base.html" %}
{% block title %}Add books{% endblock %}
{% block extracss %}
<style>
.top-buffer { margin-top:20px; }
.bs-docs-nav { background-color: #563d7c; }
</style>
{% endblock extracss %}
{% block content %}
<form action="" method="post" class="form-horizontal" role="form">{% csrf_token %}
<div class="row top-buffer">
<div class="col-md-1">
{{form.title.label_tag}}
<input type="text" value="" class=""/>
</div>
</div>
<div class="row top-buffer">
<div class="col-md-1">
{{form.author.label_tag}}
<input type="text" value="" class=""/>
</div>
</div>
<div class="row top-buffer">
<div class="col-md-2 col-md-offset-1">
<input type="submit" value="Save" class="btn btn-primary btn-lg"/>
</div>
</div>
</form>
{% endblock %}
base.html
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{{title|default:"Book Library"}}{% endblock %}</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
{% block extracss %}{% endblock extracss %}
</head>
<body>
<div class="container">
<div class="navbar-header">
Books Portal
</div>
{% block content %}
{% endblock %}
</div>
{% block extrajs %}{% endblock extrajs %}
</body>
</html>
details.html
{% extends "books_portal/base.html" %}
{% block title %}Details{% endblock %}
{% block extracss %}
<style>
.top-buffer { margin-top:20px; }
.bs-docs-nav { background-color: #4CD085; }
</style>
{% endblock extracss %}
{% block content %}
<div class="row top-buffer">
<div class="col-md-1">
<strong>Title:</strong>
</div>
<div class="col-md-2">
{{book.title}}
</div>
</div>
<div class="row top-buffer">
<div class="col-md-1">
<strong>Author:</strong>
</div>
<div class="col-md-2">
{{book.author}}
</div>
</div>
<div class="row top-buffer">
</div>
<div class="row">
<div class="col-md-1 col-md-offset-1 text-center">OK</div>
</div>
{% endblock %}
index.html
{% extends "books_portal/base.html" %}
{% block title %}Collection of books{% endblock %}
{% block extracss %}
<style>
.top-buffer { margin-top:20px; }
.bs-docs-nav { background-color: #563d7c; }
</style>
{% endblock extracss %}
{% block content %}
<table class="table table table-hover">
<tr>
<th class="text-center">Title</th>
<th class="text-center">Author</th>
<th class="text-center">Edit</th>
</tr>
{% for book in books_list %}
<tr>
<td class="text-center">{{ book.title }}</td>
<td class="text-center">{{ book.author }}</td>
<td class="text-center">Delete</td>
</tr>
{% endfor %}
</table>
<div class="row">
<div class="col-md-2 col-md-offset-5 text-center">Add</div>
</div>
{% endblock %}
Currently i cant add or delete any books, any help will be appreciated. Thank you.
I've cut and pasted all your code, plus a relevant urls.py, into a new project. The immediate problem is that you're not showing any form errors in your add.html. You can just add {{ form.errors }} at the top of the template.
Once you've done that, you'll see the actual issue: you're not providing all relevant fields when creating your book. In fact, Django can't see any fields, because you haven't given any of the inputs name attributes. Really, you shouldn't create the input elements manually: you should get Django to do that, because then it also takes responsibility for prepopulating the field with the existing value either when re-showing the form with errors, or when editing an existing Book. It should look like this:
{{ form.title.label_tag }}
{{ form.title }}
{{ form.title.errors }}
Then the outstanding issue is that you're not including the isbn or pages fields, which your model is treating as required. You can either set them as blank=False in the model, or use an exclude list in the ModelForm. Either way, you'll need null=False in the model field for pages.
Or, of course, you can add them to the form. To be honest, the easiest thing for you to do now, while you're learning, is to replace all the HTML inside your <form> tag with just {{ form.as_p }}, so that Django outputs everything for you.
I'm utilizing the Django Bootstrap Toolkit for styling my website and have run into a slight issue. I am trying to have a form embedded within my base HTML that is essentially a user switch, whereby given a list of names, the user can decide whether he or she wants to switch users while utilizing the site rather than be logged in as "Guest" (the site is internal, so there's no real need for credential authentication). The views I have are such:
from django.shortcuts import render, render_to_response, redirect
from django.template import RequestContext
from django.http import HttpResponse, Http404
import datetime
myUsers = ['User A', 'User B', 'User C', 'User D', 'User E', 'Guest']
def index(request):
# make login default guest if not logged in
if not 'myUser' in request.session:
request.session['myUser'] = 'Guest'
# grab user if we've submitted login form from this page
if request.method == 'POST':
if 'myUser' in request.POST:
request.session['myUser'] = request.POST['myUser']
return render(request, 'home/index.html', {'myUsers': myUsers})
def login(request, myUser):
request.session['myUser'] = myUser
return redirect('index')
The base HTML template that contains the form is the following:
{% load bootstrap_toolkit %}
<html>
<head>
<title>{% block title %}{% endblock %}</title>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
{% bootstrap_javascript_tag %}
</head>
<body>
{% block header %}
<h3 style="font-family: Source Sans Pro, Myriad Pro; font-size: 16px; margin-left: 20px">
{% if request.session.myUser %}
Current User: {{ request.session.myUser}}
<div class="navbar">
<form class="navbar-form pull-left" action="" method="post" id="myUser">
{% csrf_token %}
<select name id class="form-control" style="width: 200px;">
{% for myUser in myUsers %}
<option value="{{ myUser }}">{{ myUser }}</option>
{% endfor %}
</select>
<button id="formSubmit" type="submit" class="btn btn-default">Change User</button>
</form>
</div>
{% else %}
No User Logged In
<div class="navbar">
<form class="navbar-form pull-left" action="" method="post" id="myUser">
{% csrf_token %}
<select name id class="form-control" style="width: 200px;">
{% for myUser in myUsers %}
<option value="{{ myUser }}">{{ myUser }}</option>
{% endfor %}
</select>
<button id="formSubmit" type="submit" class="btn btn-default">Login</button>
</form>
</div>
{% endif %}
</h3>
{% endblock %}
<hr>
<h1 style="text-align:center; font-family: Myriad Pro; font-size: 60px; padding: 10px">MySite</h1>
<div style="text-align:center" name="content">
{% block content %}
{% endblock %}
</div>
{% block footer %}
{% endblock %}
</body>
</html>
I get default Guest login, which is not a problem, but I do not unfortunately get any kind of user switching when the user clicks on the dropdown menu and selects another individual. It is likely I am missing something, but I unfortunately have been unable to figure it out if so. Help is very much appreciated!
Your problem is the following, <select name id class="form-control" style="width: 200px;">
You haven't specified the name of your <select></select> form field.
Simply modify your code to include the proper form field name.
<select name="myUser" class="form-control" style="width: 200px;">
Note that its highly recommended that you use a Django Form to process the form data.