I need to show fields title and text in separate text area in my template. I can't access them cause I am new in django here are my models.py
class Banner(models.Model):
title = models.CharField(max_length=100)
text = models.CharField(max_length=500)
def __str__(self):
return self.title
and views.py
def home(request):
context = {}
return render(request, 'home/home.html', context)
First import the model and use queryset to get all the data and then return it to view using render and use the pass content wherever you want in view
from .models import Banner
def home(request):
queryset = Banner.objects.all()
context = {
'object_list': queryset
}
return render(request, 'home/home.html', context)
In you views html file you can use following:
{% for obj in object_list %}
{{ obj.title }}
{% endfor %}
Your views is lack of information, you should import and call your objects
from .models import Banner
def home(request):
context = {}
context['banners'] = Banner.objects.all()
return render(request, 'home/home.html', context)
In your html you can call
{% for banner in banners %}
{{ banner.title }}
{% endfor %}
Related
I have a problem with creating a view with data from the database. I created a view that should download data from videos (var films) and display them, unstable
views.py
from .models import Films
def index(request):
filmy = Films.objects
return render(request, 'films/index.html',{'filmy':filmy})
index.html
<h1>Films</h1>
{% for film in films.all %}
{{filmy.summary}}
<br>
{% endfor %}
models.py
class Films(models.Model):
image = models.ImageField(upload_to='images/')
summary = models.CharField(max_length=200)
def __str__(self):
return self.summary
I only have a blank page.
Your views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import Films
# Create your views here.
def index(request):
films = Films.objects.all()
return render(request, 'films/index.html',{'films':films})
In index.html
{% for film in films %}
<p> {{film.summary}} </p>
{% endfor %}
I hope that helps.
I am trying to send a form with an image, I select the image but I always get: "this field is required" when I send the form.
here is my code:
models.py:
from django.db import models
from django.contrib.auth.models import User
class Picture(models.Model):
created_at = models.DateField(auto_now_add=True)
update_at = models.DateField(auto_now=True)
image = models.ImageField()
caption = models.CharField(max_length=50)
author = models.ForeignKey('auth.user', on_delete=models.CASCADE, related_name='pictures')
forms.py:
from django import forms
class PictureForm(forms.Form):
image = forms.ImageField()
caption = forms.CharField(max_length=50)
views.py:
from django.shortcuts import render
from django.http import HttpResponseRedirect
from .models import Picture
from .forms import PictureForm
from django.contrib.auth.models import User
def pictures_view(request):
pictures = Picture.objects.all()
context = {'pictures': pictures}
return render(request, 'pictures/pictures.html', context)
def picture_form_view(request):
if request.method == 'POST':
form = PictureForm(request.POST, request.FILES)
if form.is_valid():
clean_data = form.cleaned_data()
Picture.objects.create(clean_data)
return HttpResponseRedirect('/')
else:
form = PictureForm()
return render(request, 'pictures/picture_form.html', {'form': form})
HTML:
{% extends 'pictures/base.html' %}
{% block title %}publish{% endblock %}
{% block content %}
<form class="form" action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
{% endblock %}
And a Little question, how can I complete the field author automaticly with the actual user?
first of all ImageField in model takes one compulsory argument upload_to so in your models
class Picture(models.Model):
###
image = models.ImageField(upload_to='upload/to/path')
###
now in your view
def picture_form_view(request):
if request.method == 'POST':
form = PictureForm(request.POST, request.FILES)
if form.is_valid():
clean_data = form.cleaned_data()
Picture.objects.create(**clean_data)
return HttpResponseRedirect('/')
else:
form = PictureForm()
return render(request, 'pictures/picture_form.html', {'form': form})
and to save current logged in user as default override form_valid()
method in Form class like
def form_valid(self, form):
form.instance.created_by = self.request.user
return super().form_valid(form)
Try to set enctype to "multipart/form-data" in the form tag.
<form action="#" method="post" enctype="multipart/form-data">
input here ...
</form>
If I have models like this:
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=255)
class Book(models.Model):
publisher = models.ForeignKey('Publisher')
title = models.CharField(max_length=255)
class BookImage(models.Model):
book = models.ForeignKey('Book')
file = models.ImageField(max_length=255)
title = models.CharField(max_length=255)
I want to make a page that:
Lists all the Books for a particular publisher (e.g. Book.objects.filter(publisher=34)).
For each Book, displays any existing BookImages.
For each Book displays 3 forms for uploading and titling new BookImages.
One submit button.
I don't need to edit the details of the Books - the forms are only for BookImages.
I'm getting in a tangle with modelformset_factory and inlineformset_factory and none of it is right... I feel like I'm making things too complicated. Any ideas?
Update:
Here are some things I've tried that head in a sort-of-right direction, but I'm not sure they help:
# Forms for multiple Books for this Publisher
# But I don't think I need forms for the Books in my situation?
my_publisher = Publisher.objects.get(pk=37)
BookFormSet = modelformset_factory(Book, fields=(['title']))
formset = BookFormSet(queryset=Book.objects.filter(publisher=my_publisher))
# Multiple BookImages on one Book:
# Good, but how do I do this for all of a Publisher's Books, and display existing BookImages?
my_book = Book.objects.get(pk=42)
BookImageFormSet = inlineformset_factory(Book, BookImage, fields=('file', 'title'))
formset = BookImageFormSet(instance=my_book)
I found an example of how to do this in this blog post. Below I've rewritten the example using my Publisher/Book/BookImage models, and generic class-based views, for future reference.
The form also allows the user to edit the titles of the Books, which wasn't what I originally wanted, but this seems easier than not doing it; the inline Book forms require at least one field each, so we may as well include the Book's title.
Also, to see how this worked, I've put together a small Django project using this code, and a little more detail, available on GitHub.
models.py:
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=255)
class Book(models.Model):
title = models.CharField(max_length=255)
publisher = models.ForeignKey('Publisher', on_delete=models.CASCADE)
class BookImage(models.Model):
book = models.ForeignKey('Book', on_delete=models.CASCADE)
image = models.ImageField(max_length=255)
alt_text = models.CharField(max_length=255)
forms.py:
from django.forms.models import BaseInlineFormSet, inlineformset_factory
from .models import Publisher, Book, BookImage
# The formset for editing the BookImages that belong to a Book.
BookImageFormset = inlineformset_factory(
Book,
BookImage,
fields=('image', 'alt_text')),
extra=1)
class BaseBooksWithImagesFormset(BaseInlineFormSet):
"""
The base formset for editing Books belonging to a Publisher, and the
BookImages belonging to those Books.
"""
def add_fields(self, form, index):
super().add_fields(form, index)
# Save the formset for a Book's Images in a custom `nested` property.
form.nested = BookImageFormset(
instance=form.instance,
data=form.data if form.is_bound else None,
files=form.files if form.is_bound else None,
prefix='bookimage-%s-%s' % (
form.prefix,
BookImageFormset.get_default_prefix()),
)
def is_valid(self):
"Also validate the `nested` formsets."
result = super().is_valid()
if self.is_bound:
for form in self.forms:
if hasattr(form, 'nested'):
result = result and form.nested.is_valid()
return result
def save(self, commit=True):
"Also save the `nested` formsets."
result = super().save(commit=commit)
for form in self.forms:
if hasattr(form, 'nested'):
if not self._should_delete_form(form):
form.nested.save(commit=commit)
return result
# This is the formset for the Books belonging to a Publisher and the
# BookImages belonging to those Books.
PublisherBooksWithImagesFormset = inlineformset_factory(
Publisher,
Book,
formset=BaseBooksWithImagesFormset,
fields=('title',),
extra=1)
views.py:
from django.http import HttpResponseRedirect
from django.views.generic import FormView
from django.views.generic.detail import SingleObjectMixin
from .forms import PublisherBooksWithImagesFormset
from .models import Publisher, Book, BookImage
class PublisherUpdateView(SingleObjectMixin, FormView):
model = Publisher
success_url = 'publishers/updated/'
template_name = 'publisher_update.html'
def get(self, request, *args, **kwargs):
# The Publisher whose Books we're editing:
self.object = self.get_object(queryset=Publisher.objects.all())
return super().get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
# The Publisher whose Books we're editing:
self.object = self.get_object(queryset=Publisher.objects.all())
return super().post(request, *args, **kwargs)
def get_form(self, form_class=None):
"Use our formset of formsets, and pass in the Publisher object."
return PublisherBooksWithImagesFormset(
**self.get_form_kwargs(), instance=self.object)
def form_valid(self, form):
form.save()
return HttpResponseRedirect(self.get_success_url())
templates/publisher_update.html:
{% extends 'base.html' %}
{% block content %}
<form action="" method="post" enctype="multipart/form-data">
{% for hidden_field in form.hidden_fields %}
{{ hidden_field.errors }}
{{ hidden_field }}
{% endfor %}
{% csrf_token %}
{{ form.management_form }}
{{ form.non_form_errors }}
{% for book_form in form.forms %}
{# Output a Book form. #}
{% for hidden_field in book_form.hidden_fields %}
{{ hidden_field.errors }}
{% endfor %}
<table>
{{ book_form.as_table }}
</table>
{# Check if our `nested` property exists, with BookImage forms in it. #}
{% if book_form.nested %}
{{ book_form.nested.management_form }}
{{ book_form.nested.non_form_errors }}
{% for bookimage_form in book_form.nested.forms %}
{# Output the BookImage forms for this Book. #}
{% for hidden_field in bookimage_form.hidden_fields %}
{{ hidden_field.errors }}
{% endfor %}
<table>
{{ bookimage_form.as_table }}
</table>
{% endfor %}
{% endif %}
{% endfor %}
<input type="submit" value="Update books">
</form>
{% endblock content %}
All formset_factory methods require a form which they can generate multiple times. So, you need to create a form (since you are using Models, you need to create a model form) for BookImage.
forms.py
class BookImageForm(ModelForm):
class Meta:
model = BookImage
# book field wont be generated in the template if it is excluded
exclude = ['book',]
views.py
from django.forms.formsets import formset_factory
def your_view(request):
# I'm just including the formset code which you need, im assuming you have the remaining code in working condition
# TO HANDLE NORMAL RENDERING OF FORM WHEN USER OPENS THE WEBPAGE
if request.method == "GET":
bookimage_form = BookImageForm()
bookimage_formset = formset_factory(bookimage_form, max_num=3)
return render(request, 'index.html', {'bookimage_formset': bookimage_formset})
# WHEN USER SUBMITS THE FORM
if request.method == "POST"
# Consider BookImageFormSet as a placeholder which will be able to contain the formset which will come through POST
BookImageFormSet = modelformset_factory(BookImage, BookImageForm, max_num=3)
# bookimage_formset is a variable which stores the Formset of the type BookImageFormSet which in turn is populated by the data received from POST
bookimage_formset = BookImageFormSet(request.POST)
# HIDDEN AUTO GENERATED FIELDS ARE CREATED WHEN THE FORMSET IS RENDERED IN A TEMPLATE, THE FOLLOWING VALIDATION CHECKS IF THE VALUE OF THE HIDDEN FIELDS ARE OKAY OR NOT
if bookimage_formset.is_valid():
# EACH FORM HAS TO BE INDIVIDUALLY VALIDATED, THIS IS NORMAL FORM VALIDATION. ONLY DIFFERENCE IS THAT THIS IS INSIDE A FOR LOOP
for bookimage_form in bookimage_formset:
if bookimage_form.is_valid:
bookimage_form.save()
return HttpResponse("Form saved!")
return HttpResponseRedirect('/')
PS: You can get the data from request.POST for other models in the same view to handle other data (such as the data for Books)
My project is here github Project
I'm getting this error.
ValueError at /salesapp/add/ashton-aged-maduro/
The view salesapp.views.add_CartItem didn't return an HttpResponse object. It returned None instead.
I get this error when I click the 'Add to Cart' button on my singleproduct.html template which calls the ProductAddToCart form. The view is add_CartItem.
I also get the error Field is required when I don't initially set the form values. I'm just stuck now.
This is models.py
class Product(models.Model):
itemid = models.CharField(max_length=128, unique=True)
itemname = models.CharField(max_length=128)
brand = models.CharField(max_length=128)
image = models.ImageField(upload_to='static/images/')
notes = models.CharField(max_length=250)
price = models.IntegerField()
slug = models.SlugField(unique=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.itemname)
super(Product, self).save(*args, **kwargs)
def __str__(self):
return self.itemname
class CartItem(models.Model):
cart_id = models.CharField(max_length=50)
date_added = models.DateTimeField(auto_now_add=True)
quantity = models.IntegerField(default=1)
itemid = models.ForeignKey('Product', unique=False)
class Meta:
db_table = 'cart_items'
ordering = ['date_added']
def name(self):
return self.product.name
My forms.py
class ProductAddToCartForm(forms.ModelForm):
cart_id = forms.CharField(max_length=50)
date_added = forms.DateTimeField()
quantity = forms.IntegerField()
slug = forms.CharField(widget=forms.HiddenInput(), required=False)
#itemid = models.ForeignKey('Product', unique=False)
class Meta:
model = CartItem
fields = ('cart_id', 'date_added', 'quantity', 'slug', 'itemid', )
My views.py
def add_CartItem(request, product_name_slug):
print('In add_CartItem --------------------')
form = ProductAddToCartForm(request.POST)
p = Product.objects.get(slug=product_name_slug)
form = ProductAddToCartForm(initial={'cart_id': 123, 'date_added':date.date.today(), 'quantity': 1, 'slug':p.slug, 'id':p.id, 'itemid':p.itemid})
form.save(commit=False)
print(form)
print(p.slug)
print(p.id)
print(p.itemid)
if form.is_valid():
print(p)
print('In form.is_valid()--------------------------------')
ci = CartItem.objects.create(cart_id=1, date_added=date.date.today(), quantity=1, itemid=p)
form.save(commit=True)
return index(request)
else:
print(form.errors) #return render(request, 'salesapp/errors.html', {'form': form})
My urls.py
from django.conf.urls import url
from salesapp import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'about/', views.about, name='about'),
url(r'customers/', views.customers, name='customers'),
url(r'products/', views.products, name='products'),
url(r'^add_product/$', views.add_product, name='add_product'),
url(r'^add_customer/$', views.add_customer, name='add_customer'),
url(r'items/(?P<product_name_slug>[\w\-]+)/$', views.show_product, name='show_product'),
url(r'^add/(?P<product_name_slug>[\w\-]+)/$', views.add_CartItem, name='add_CartItem'),
#url(r'^cart/$', views.show_cart, name='show_cart'),
#url(r'^register/$', views.register, name='register'),
#url(r'^login/$', views.user_login, name='login'),
#url(r'^logout/$', views.user_logout, name='logout'),
#url(r'^restricted/', views.restricted, name='restricted'),
]
and my template where I want to display the ProductAddToCartForm but add a product to the CartItem table.
<!DOCTYPE html>
{% extends 'salesapp/base.html' %}
{% load staticfiles %}
{% block title_block %}
{{ product.itemname }}
{% endblock %}
{% block body_block %}
<div>
<div>
<ul style="list-style:none; text-align:center;">
<li style="float:left; width:25%; margin:20px;">
<img src="/{{ product.image }}"/>
<div>
<b>{{ product.itemname }}</b><br/>
Price per cigar:<br/>
<b>${{ product.price }}</b>
<p>{{ product.notes }}</p>
</div>
<form method="post" action="/salesapp/add/{{ product.slug }}/" class="cart">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
{{ field.errors }}
{{ field.help_text }}
{{ field }}
{% endfor %}
<br />
<input type="submit" value="Add To Cart" name="submit" alt="Add To Cart" />
</form>
<div class="cb"></div>
</li>
</ul>
</div>
<!-- More code -->
</div>
{% endblock %}
A view function in django should either return a json or a dict or can return a Webpage
You can either do one of following
1) return a json or dict
return {"value1":"value","value2":"value"}
2)redirect to a web page
return redirect('/some/url/')
3)return Http response
return HttpResponse(status=<status code>,content="some content")
4)render a template
t = loader.get_template('myapp/index.html')
c = {'foo': 'bar'}
return HttpResponse(t.render(c, request),
content_type='application/xhtml+xml')
Because you did not return any response to the view,
According to the docs
A view function is simply a Python function that
takes a Web request and returns a Web response.
You need to return to use render method for initial rendering of form and for redirection to another view you can use redirect method of Django.
A view function must return an HttpResponse. For example, if the process was successfull and you dont want to return anything, you can return HttpResponse(status=200)
When a view handles forms, you have to split GET and POST requests. In the GET part you need to instantiate the form without data. In the POST part you fill the form with request.POST data. And this data must have ALL mandatory fields. A typical view function scheme to handle a form is the folowing:
def view(request):
if request.method == "GET":
form = MyForm()
return ...
if request.method == "POST":
form = MyForm(request.POST)
form.save()
return ...
In your template, you have to show all form fields. Then, all form fields will be passed with the request. If you dont, you need to fill the form fields in the view.
first delete the prints, almost when you make a question, are useless in Django
def add_CartItem(request, product_name_slug):
form = ProductAddToCartForm(request.POST)
if request.method == 'POST':
if form.is_valid():
ci = CartItem.objects.create(cart_id=1, date_added=date.date.today(), quantity=1, itemid=p)
ci.save()#you save your model changes, not your form
return HttpResponseRedirect(reverse('your:url'))#your return the success url or the same
else:
#here error, if form isn't valid
else:
form = ProductAddToCartForm(request.POST)
return render(request, 'your/template.html', {'form': form})
That is the correct way to work with forms in Django, first you must make a if statement asking to the browser if is a post request or a normal request, if is post request, take the data from the forms and are adding to the database, if not, Django return a empty template form.
Let me know if you problem solve
I just want to add fields dynamically like Django admin . ( + ) and ( - ) button must perform add and delete img_formset using javascript
The below code is taken from a tutorial I got from web and its working fine. But for now I just need to know how to extend this code do the above.
models.py
from django.db import models
class Pet(models.Model):
name = models.CharField(max_length=100)
breed = models.CharField(max_length=100)
def __unicode__(self):
return self.name
class PetImage(models.Model):
image = models.ImageField(upload_to='pets')
pet = models.ForeignKey(Pet)
created = models.DateTimeField(auto_now_add=True)
#Delete Path
def delete(self, *args, **kwargs):
self.image.delete(False)
super(PetImage, self).delete(*args, **kwargs)
forms.py
from django.forms.models import inlineformset_factory
from django import forms
from .models import Pet, PetImage
class PetForm(forms.ModelForm):
class Meta:
model = Pet
PetImageFormset = inlineformset_factory(Pet, PetImage,
fields=('image',), can_delete=True)
urls.py
from django.conf.urls import *
urlpatterns = patterns('pets.views',
url(r'^add/$', 'add_pet', name='add_pet'),
url(r'^update/(\d+)/$', 'update_pet', name='update_pet'),
)
views.py
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from .forms import PetForm, PetImageFormset
from .models import Pet, PetImage
def add_pet(request):
form = PetForm()
img_formset = PetImageFormset(instance=Pet())
if request.method == 'POST':
form = PetForm(request.POST)
if form.is_valid():
pet = form.save()
img_formset = PetImageFormset(request.POST,
request.FILES, instance=pet)
if img_formset.is_valid():
img_formset.save()
return HttpResponseRedirect(reverse('pets:home'))
return render(request, "form.html", {
'form': form,
'img_formset': img_formset,
'action': "Create"
})
def update_pet(request, pet_id):
pet = get_object_or_404(Pet, pk=pet_id)
form = PetForm(instance=pet)
img_formset = PetImageFormset(instance=pet)
if request.method == 'POST':
form = PetForm(request.POST, instance=pet)
if form.is_valid():
pet = form.save(commit=False)
img_formset = PetImageFormset(request.POST,
request.FILES, instance=pet)
if img_formset.is_valid():
pet.save()
img_formset.save()
return HttpResponseRedirect(reverse('pets:home'))
return render(request, "form.html", {
'form': form,
'img_formset': img_formset,
'action': "Update"
})
form.html
{% extend "base.html" %}
{% block title %}Pet{% endblock title %}
{% block content %}
<h4>{{ action }}</h4>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
{{ img_formset.as_p }}
</form>
{% endblock content %}