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.
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>
Am creating a website where user will be posting information in the site, but when I post in the site, all post appear in a single card while I want each post to appear in a separate card, How would I do this?? would I have to use Javascript in the front end or python in the back end to accomplish this, and how?
Am using python 3.6.8, and django 2.1.8, I have written a code but all post appear in single materialize card
views
def homepage(request):
return render(request=request,
template_name="main/home.html",
context={"documents":Documents.objects.all}
models
class Documents(models.Model):
docs_name = models.CharField(max_length=200)
police_station = models.CharField(max_length=200)
docs_details = models.TextField()
docs_pic = models.ImageField()
def __str__(self):
return self.docs_name
Home template
{% extends 'main/base.html' %}
{% block content %}
<a class="waves-effect waves-light btn" href="">button</a>
<div class="row">
<div class="col s12 m9" >
<div class="card">
<div class="card-image">
{% for Doc in documents %}
<p>{{Doc.docs_name}}</p>
<p>{{Doc.police_station}}</p>
<p>{{Doc.docs_details}}</p>
<p>{{Doc.docs_pic}}</p>
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}
Try:
{% extends 'main/base.html' %}
{% block content %}
<a class="waves-effect waves-light btn" href="">button</a>
<div class="row">
<div class="col s12 m9" >
{% for Doc in documents %}
<div class="card">
<div class="card-image">
<p>{{Doc.docs_name}}</p>
<p>{{Doc.police_station}}</p>
<p>{{Doc.docs_details}}</p>
<p>{{Doc.docs_pic}}</p>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
You can achieve what you desire by simply adding the looping construct outside the <div class="card"> like this :
{% extends 'main/base.html' %}
{% block content %}
<a class="waves-effect waves-light btn" href="">button</a>
<div class="row">
<div class="col s12 m9" >
{% for Doc in documents %}
<div class="card">
<div class="card-image">
<p>{{Doc.docs_name}}</p>
<p>{{Doc.police_station}}</p>
<p>{{Doc.docs_details}}</p>
<p>{{Doc.docs_pic}}</p>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
This way your card section alone repeats multiple times.
Earlier since the loop was within the card you got all the items within the same card.
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.
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 trying to make a layout for a bookstore app... I have installed bootstrap through command line and I am trying to load simplex theme.
I am getting this error
TemplateSyntaxError at /store/
'bootstrap_styles' received some positional argument(s) after some keyword argument(s)
Also, when I delete that line of code and try to execute it I get error of {% endblock %}
this..
TemplateSyntaxError at /store/
Invalid block tag: 'endblock'
Here is my base.html
{% extends 'bootstrap3/bootstrap3.html' %}
{% load staticfiles %}
{% load bootstrap3 %}
{% load bootstrap_themes %}
{% bootstrap_styles theme='simplex' type ='min.css' %}
{% block bootstrap3_extra_head %}
<link href = "http://fonts.googleapis.com/css?family=Open+Sans:400,300,700" rel = "stylesheet" type="text/css"/>
<link href = "{% static 'base/css/style.css' %}" rel = "stylesheet" type="text/css"/>
{% endblock %}
{% block bootstrap3_title %}
{%block title %}
Welcome to Pick A Book !!
{%endblock %}
{% endblock %}
{ block bootstrap3_content %}
<nav class = "navbar navbar-inverse navbar-fixed-top">
<div class = "container">
<div class = "navbar-header">
<button type="button" class ="navbar-toggle" data-toggle="collapse" data-target = "#navbar">
<span class = "icon-bar"> </span>
<span class = "icon-bar"> </span>
<span class = "icon-bar"> </span>
</button>
Pick A Book
</div>
<div id = "navbar" class ="collapse navbar-collapse">
<ul class ="nav navbar-nav">
<li class = "hvr=curl-top-right">Home </li>
<li class = "hvr=curl-top-right"> About </li>
<li class = "hvr=curl-top-right">Contact </li>
</ul>
<div class = "navbar-form pull-right">
{% if request.user.is_authenticated %}
Welcome {% if request.user.first_name %}
{{ request.user.first_name }}
{% else %}
{{ request.user.username }}
{% endif %}! Log Out
{% else %}
Welcome, Log In or <a href="{% url 'registration_register' %}" > Register</a>
{% endif %}
</div>
</div>
</div>
</nav>
<div class = "container-fluid">
<img src = "{% static 'base/img/header_full.jpg' %}" class ="bg">
<div class = "parallax">
<div class ="row">
{ % block body %}
<div class = "col-md-8 col-md-offset-2 col-sm-12 maincontent">
Welcome to our Store.
</div>
{%endblock%}
</div>
</div>
</div>
<div class = "row text-center navbar footer">
<div class = "col-md-12">
<p> 2017 Pick A Book. Developed by Kshitij Rangari </p>
</div>
</div>
{%endblock%}
There is a few syntax errors
{% block bootstrap3_title %}
{%block title %} #<<<<<<<<<<<<<<< {% block title %}
Welcome to Pick A Book !!
{%endblock %} #<<<<<<<<<<<<<<<< {% endblock %}
{% endblock %}
{ block bootstrap3_content %} #<<<<<<<<<<<<<<<< missing % after {