The Django docs aren't clear on using ModelForm. First, how do I set up my urls.py?
I simply do this:
from . import views as music_views
url(r'album/add/$', music_views.AlbumCreate(), name='album-add'),
In my views I'm trying to use the AdminDateWidget:
from . import models as music_models
from django import forms
from django.contrib.admin.widgets import AdminDateWidget
class AlbumCreate(forms.ModelForm):
class Meta:
releasedate = forms.DateField(widget=AdminDateWidget())
model = music_models.Album
fields = ['artist', 'album_title', 'genre', releasedate, 'notes', 'album_logo', 'rating']
My template is:
{% for field in form %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.errors }}</span>
</div>
<label class="control-label col-sm-2">
{{ field.label_tag }}
</label>
<div class="col-sm-10">
{{ field }}
</div>
</div>
{% endfor %}
My struggle here is that I am getting this error when rendering the page:
Exception Value:
sequence item 0: expected str instance, DateField found
But according to the https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/ docs, DateField is one of the allowable datatypes. So I am obviously doing it wrong somehow, but don't know how to do it right. Can someone help me out on this? I tend to prefer ground up examples to study from, if possible.
At a glance, it seems there are many problems (no form tags in template, fields can only accept strings, etc.) But most importantly for those wanting to use AdminDateWidget: there are a number of extra scripts you need to load which are NOT included in the usual {{ form.media }}.
project/urls.py
from django.conf.urls import include, url
from album.views import album_add
urlpatterns = [
url(r'album/add/$', album_add, name='album-add'),
]
album/models.py
from django import forms
from django.db import models
from django.contrib.admin.widgets import AdminDateWidget
class Album(models.Model):
artist = models.CharField(max_length=30)
releasedate = models.DateField()
class AlbumForm(forms.ModelForm):
releasedate = forms.DateField(widget=AdminDateWidget)
class Meta:
model = Album
fields = ['artist', 'releasedate']
album/views.py
from .models import AlbumForm
from django.shortcuts import render, HttpResponse
def album_add(request):
if request.method == "GET":
form = AlbumForm()
return render(request, 'album/create_album.html', {'form': form})
elif request.method == "POST":
form = AlbumForm(request.POST)
if form.is_valid():
form.save()
return HttpResponse("Saved.")
return render(request, 'album/create_album.html', {'form': form})
album/templates/album/create_album.html
{% load static %}
<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="{% static 'admin/js/core.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/vendor/jquery/jquery.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/jquery.init.js' %}"></script>
{{ form.media }}
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/base.css' %}" />
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/widgets.css' %}" />
<form>
{% csrf_token %}
<table>
{{ form }}
</table>
<input type="submit" value="Go!">
</form>
I hope this helps someone!
I found a solution:
admin_forms.py
First add widgets of type AdminDateWidget to your date fields. You will need to assign a custom name as css class attribute (autocomplete=off is optional, disables autofill)
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ('date_start', 'date_end',)
widgets = {
'date_start': AdminDateWidget(
attrs={'class': 'picker', 'autocomplete': 'off'}),
'date_end': AdminDateWidget(
attrs={'class': 'picker', 'autocomplete': 'off'}),
}
template.html
Secondly, load necessary resources (datepicker.css)and customise the action of your date fields with class 'picker' or any name you assigned to your css class. Check the code in the script tag. IMPORTANT: For some reason the script tags need to be after the styles to work.
{% extends "admin/base_site.html" %}
{% load i18n %}
{% block content %}
<style rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.css" />
<style>
... Other CSS ...
</style>
<script>
grp.jQuery(function () {
grp.jQuery(".picker").datepicker({dateFormat: 'yy-m-d'});
});
</script>
<form action="{{ action_url }}" method="post" id="my_form">
{% csrf_token %}
<section>
<fieldset class="module grp-module">
{% for field in form %}
<label>{{ field.label }}</label>
{{ field }}
{% endfor %}
</fieldset>
</section>
</form>
{% endblock %}
Access to /admin/jsi18n/ requires superuser authentication in Django v.2.0.7. The following line will not work for non-superusers:
<script type="text/javascript" src="/admin/jsi18n/"></script>
The workaround is to copy script from this URL to jsi18n.js (being authenticated as a superuser). Please, note that under each LOCAL_LANGUAGE jsi18n.js has different version, so if you have more then one target LOCAL_LANGUAGE you will need to save different versions of jsi18n.js.
Related
I am trying to display the search bar which when searched will display the entries of the form.
However It is not happening. I am using Django Filters to filter the form so that end customer will be able to search for the query and find the required details.
I am pasting the whole code below, If you think there is a better way than this to get the work done please do let me know.
I am also sharing the link of the Github repository incase if you would like to try and see the error.
I am stucked with this error from long time. NEED HELP VERY BADLY!!!!!
filters.py
import django_filters
from .models import *
from inventory_app.models import Form1
class ItemFilter(django_filters.FilterSet):
item = django_filters.CharFilter(field_name='item', lookup_expr='icontains')
class Meta:
model = Form1
fields = ['item']
models.py
from django.db import models
#from django.utils import timezone
# Create your models here.
class Form1(models.Model):
item = models.CharField(max_length=125)
quantity = models.IntegerField(default=0)
vendor = models.CharField(max_length=125)
inward = models.IntegerField(default=1234)
date = models.DateField()
def __str__(self):
return self.item
# security_stamp_date = models.DateField(default=timezone.now)
Form1_entries.html
{% extends 'base.html' %}
{% block title %} Form 1 Entries {% endblock %}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
{% block body %}
<div>
<form method="GET" class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
{{myFilter.Form}}
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
{% for entry in entries %}
<table class="table table-bordered">
{{ entry.item }}
{{ entry.quantity }}
{{ entry.vendor }}
{{ entry.inward }}
{{ entry.date }}
</table>
{% endfor %}
<div class="container">
<div class="row p-5">
Download the CSV file
</div>
</div>
{% endblock %}
GITHUB repository:
https://github.com/samatharkar/altiostar
>>> from django.db.models import Q
>>> queryset = User.objects.filter(
Q(first_name__startswith='R') | Q(last_name__startswith='D')
)
>>> queryset
<QuerySet [<User: Ricky>, <User: Ritesh>, <User: Radha>, <User: Raghu>, <User: rishab>]>
im newbie in django. I have some question related to models. So, i was trying to display the model name and date to the views by iterating to all of them. But somehow they dont show up in the views, i tried to search in google but none fixed my problem. Im sorry if i asked some ridiculous question, but here is my code.
And also i already checked my models and theyre valid
Models
from django.db import models
from django.utils import timezone
from django.utils.text import slugify
class Post(models.Model):
title = models.CharField(max_length=30)
body = models.TextField()
time_post = models.DateTimeField(auto_now_add=True)
time_edit = models.DateTimeField(editable=False,blank = True)
slug = models.SlugField(editable=False, blank=True)
def save(self):
self.slug = slugify(self.title)
self.time_edit = timezone.now()
super(Post, self).save()
def __str__(self):
return "{}. {}".format(self.id, self.title)
urls
from django.shortcuts import render
from .models import Post
def blog(request):
posts = Post.objects.all(),
context = {
'title':'Blog ',
'contributor':'Chris',
'img':'blog/img/BlogBanner.jpg',
'Post':posts,
'nav': [
['/blog/recent','Recent'],
['/blog/news','News'],
['/blog','Blog'],
['/about','About'],
['/', 'Index']
]
}
return render(request,'blog/blog.html',context)
My blog.html
{% extends "base.html" %}
{% load static %}
{% block app_css %} <!-- Custom CSS per app !-->
<link rel="stylesheet" types="text/css" href = "{% static "blog/css/styleblog.css" %}"> <!-- CSS OVERIDE !-->
{% endblock app_css %}
{% block header %}
<h1 class="display-4">Welcome to {{title}} | ChrisDjango</h1>
<p class="lead">This was made in Django by {{contributor}}</p>
{% endblock header %}
{% block content1 %}
{% for post in Post %}
<h2>{{post.title}}</h2> #THE TITLE AND TIMEPOST DIDNT SHOW UP
<p>{{post.time_post}}</p>
{% endfor %}
{% endblock content1 %}
base.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{%include "snippets/styles.html"%} <!--Bootstrap!-->
{% block app_css %}
<link rel="stylesheet" types="text/css" href = "{% static "blog/css/styleblog.css" %}"> <!-- Custom CSS per app !-->
{% endblock app_css %}
<title>{{title}} | ChrisDjango</title>
<img id="banner" style="border-bottom: 15px solid #343A40;" src="{% static img %}" alt="Blog Banner">
</head>
<body>
{%include "snippets/navbar.html"%}
<div class="jumbotron">
<div class="container text-white text-center">
{% block header %}
{% endblock header %}
<hr class="my-4">
</div>
</div>
<div class="container-fluid">
<div class="container bg-white text-dark shadow" style="margin-top:-150px" id="myBody">
{% block content1 %}
{% endblock content1 %}
</div>
<div class="container bg-secondary text-white shadow">
{% block content2 %}
{% endblock content2 %}
</div>
</div>
{%include "snippets/scripts.html"%}
</body>
</html>
Sorry if my code looks really weird
Thank you
Let's start with this edit in urls:
posts = Post.objects.all(),
should be
posts = Post.objects.all()
Note the dropped comma.
I have made that mistake MANY times and it is really hard to spot sometimes. Here is what happens when you have a trailing comma (you get an iterable wrapper)
If you still have a problem LMK.
There is a trailing comma at the end of:
posts = Post.objects.all(),
# trailing comma ^
this means you wrap the item in a singleton tuple. It is thus a tuple with one element, the collection of object.
You should remove the comma at the end:
posts = Post.objects.all()
I would furthermore rename 'Post' to posts, since this gives a hit that it is a collection of items.
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 am using template inheritance in my django project. I used form in my base html page and submit button, When i inherit base template to another template form get disappeared but submit button is still there. I have below templates.
base.html
<head>
{% load static from staticfiles %}
<link rel="stylesheet" href="{% static "bootstrap.css" %}">
</script>
</head>
<body>
{% block option %}
<div class="row">
<div class="col-lg-3">
<form method = "post" action="">
{% csrf_token %}
{{form}}
<input type="submit" value="Submit" />
</form>
</div>
</div>
{% endblock %}
<div class="row">
{% block content %}{% endblock %}
</div>
</body>
chart.html
{% extends 'base.html' %}
{% block content %}
<head>
{% load static from staticfiles %}
<link rel="stylesheet" href="{% static "bootstrap.css" %}">
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
</script>
</head>
<div id="container" align="center">
{{ column_chart.as_html }}
{% endblock %}
How can i make form visible there in chart html??
EDIT: Added Views
views.py
def select_chart_form(request):
form = SelectChart(request.POST)
if form.is_valid():
if (str(form.cleaned_data['status']) == '1'):
#print "Hello Naresh reverse('chart1')"
return HttpResponseRedirect('/chart1/')
if (str(form.cleaned_data['status']) == '2'):
return HttpResponseRedirect('/chart2/')
context = {
'form' : form
}
return render(request, 'base.html', context)
def video_by_user(request):
analysis = VideoData.objects.annotate(watches_count = Count('user')).order_by('-watches_count')[:10]
data_source = ModelDataSource(analysis,fields=['video_name', 'watches_count'])
column_chart = gchart.ColumnChart(data_source,options={'title': "Top 10 Videos watched by No. Of Users"})
context = {
"data_source": data_source,
"column_chart": column_chart,
}
return render_to_response('chart.html', context)
I am calling video_by_user method..after click on submit button.
The select_chart_form and video_by_user views are completely separate. The first one renders just base.html, and supplies the form variable when it does so. The second one renders chart.html, which inherits from base.html, but it only supplies the variables needed for chart.html itself: it doesn't provide the form needed for base.html. You will need to supply that in video_by_user.
I am trying to implement end less pagination in Django App but stuck at how to implement twitter like end less scrolling :
My models.py
from django.db import models
from django.contrib import admin
#------------------------------------------------------------------------------
class Book(models.Model):
name = models.CharField(max_length=50)
pub_date = models.DateField(auto_now_add=True)
class bookAdmin(admin.ModelAdmin):
"""Book admin class"""
list_display = ('name','pub_date')
ordering = ('name',)
admin.site.register(Book,bookAdmin)
My views.py :
from models import Book
from django.template import RequestContext
from django.shortcuts import render_to_response
#------------------------------------------------------------------------------
def latest_books(request,template = 'latest_books.html',
page_template = 'latest_books_page.html' ):
context = {}
book_list = Book.objects.order_by('-pub_date')
context.update( {'book_list': book_list, 'page_template': page_template,} )
# override the template and use the 'page' style instead.
if request.is_ajax():
template = page_template
return render_to_response(
template, context, context_instance=RequestContext(request) )
My 'latest_books.html' template :
<html><head><title>Books</title></head>
<body>
<h1>Books</h1>
{% block js %}
{{ block.super }}
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.2.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src="http://yourjavascript.com/337923491/endless.js" charset="utf-8"></script>
<script type="text/javascript" src="http://yourjavascript.com/151379951/endless-pagination.js"></script>
<script>$.endlessPaginate();</script>
{% endblock %}
{% block content %}
<div class="endless_page_template">
{% include page_template %}
</div>
{% endblock %}
</body></html>
My latest_books_page.html :
<h2>Viewing All Entries</h2>
{% load endless %}
<div>
<ul>
{% paginate book_list %}
{% for book in book_list %}
<li>{{ book.name }}</li> {{ book.pub_date }}
{% endfor %}
{% show_pages %}
</ul>
</div>
I am facing two issues first if i use {{ block.super }} as given in tutorial .Django gives this error 'BlockNode' object has no attribute 'context' and if i remove {{ block.super }}. I get simple pagination with next and previous functionality .
Can someone help me please. I want to implement on scroll load pagination...
Please try out my code:
views.py :
from models import Book
from django.template import RequestContext
from django.shortcuts import render_to_response
#------------------------------------------------------------------------------
def latest_books(request,template = 'latest_books.html',
page_template = 'latest_books_page.html' ):
context = {}
book_list = Book.objects.order_by('-pub_date')
context.update( {'book_list': book_list, 'page_template': page_template,} )
# override the template and use the 'page' style instead.
if request.is_ajax():
template = page_template
return render_to_response(
template, context, context_instance=RequestContext(request) )
latest_books.html :
<html><head><title>Books</title></head>
<body>
<h1>Books</h1>
<h2>Viewing All Entries</h2>
<div class="endless_page_template">
{% include page_template %}
</div>
{% block js %}
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="{{ STATIC_URL }}js/endless_on_scroll.js"></script>
<script src="{{ STATIC_URL }}js/endless-pagination.js"></script>
<script>
$.endlessPaginate({paginateOnScroll: true,
endless_on_scroll_margin : 10,
paginateOnScrollChunkSize: 5
});</script>
{% endblock %}
</body></html>
latest_books_page.html :
{% load endless %}
{% paginate 10 book_list %}
{% for book in book_list %}
{{ book.name }}<br> {{ book.pub_date }}<br><br><br>
{% endfor %}
{% show_more "even more" "working" %}
Try out and let me know ... and enter 20-30 entries into your DB to check it out properly ...
You have to include page_template before call the {{block.super}}
<h2>Entries:</h2>
{% include page_template %}
{% block js %}
{{ block.super }}
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="{{ STATIC_URL }}endless_pagination/js/endless-pagination.js"></script>
<script>$.endlessPaginate();</script>
{% endblock %}