I am having problems with django forms and image uploads. I have googled, read the documentations and even questions ere, but cant figure out the issue. Here are my files
my models
class UserProfile(User):
"""user with app settings. """
DESIGNATION_CHOICES=(
('ADM', 'Administrator'),
('OFF', 'Club Official'),
('MEM', 'Ordinary Member'),
)
onames = models.CharField(max_length=30, blank=True)
phoneNumber = models.CharField(max_length=15)
regNo = models.CharField(max_length=15)
designation = models.CharField(max_length=3,choices=DESIGNATION_CHOICES)
image = models.ImageField(max_length=100,upload_to='photos/%Y/%m/%d', blank=True, null=True)
course = models.CharField(max_length=30, blank=True, null=True)
timezone = models.CharField(max_length=50, default='Africa/Nairobi')
smsCom = models.BooleanField()
mailCom = models.BooleanField()
fbCom = models.BooleanField()
objects = UserManager()
#def __unicode__(self):
# return '%s %s ' % (User.Username, User.is_staff)
def get_absolute_url(self):
return u'%s%s/%s' % (settings.MEDIA_URL, settings.ATTACHMENT_FOLDER, self.id)
def get_download_url(self):
return u'%s%s/%s' % (settings.MEDIA_URL, settings.ATTACHMENT_FOLDER, self.name)
...
class reports(models.Model):
repID = models.AutoField(primary_key=True)
repSubject = models.CharField(max_length=100)
repRecepients = models.ManyToManyField(UserProfile)
repPoster = models.ForeignKey(UserProfile,related_name='repposter')
repDescription = models.TextField()
repPubAccess = models.BooleanField()
repDate = models.DateField()
report = models.FileField(max_length=200,upload_to='files/%Y/%m/%d' )
deleted = models.BooleanField()
def __unicode__(self):
return u'%s ' % (self.repSubject)
my forms
from django import forms
from django.http import HttpResponse
from cms.models import *
from django.contrib.sessions.models import Session
from django.forms.extras.widgets import SelectDateWidget
class UserProfileForm(forms.ModelForm):
class Meta:
model= UserProfile
exclude = ('designation','password','is_staff', 'is_active','is_superuser','last_login','date_joined','user_permissions','groups')
...
class reportsForm(forms.ModelForm):
repPoster = forms.ModelChoiceField(queryset=UserProfile.objects.all(), widget=forms.HiddenInput())
repDescription = forms.CharField(widget=forms.Textarea(attrs={'cols':'50', 'rows':'5'}),label='Enter Report Description here')
repDate = forms.DateField(widget=SelectDateWidget())
class Meta:
model = reports
exclude = ('deleted')
my views
#login_required
def reports_media(request):
user = UserProfile.objects.get(pk=request.session['_auth_user_id'])
if request.user.is_staff== True:
repmedform = reportsForm(request.POST, request.FILES)
if repmedform.is_valid():
repmedform.save()
repmedform = reportsForm(initial = {'repPoster':user.id,})
else:
repmedform = reportsForm(initial = {'repPoster':user.id,})
return render_to_response('staffrepmedia.html', {'repfrm':repmedform, 'rep_media': reports.objects.all()})
else:
return render_to_response('reports_&_media.html', {'rep_media': reports.objects.all()})
...
#login_required
def settingchng(request):
user = UserProfile.objects.get(pk=request.session['_auth_user_id'])
form = UserProfileForm(instance = user)
if request.method == 'POST':
form = UserProfileForm(request.POST, request.FILES, instance = user)
if form.is_valid():
form.save()
return HttpResponseRedirect('/settings/')
else:
form = UserProfileForm(instance = user)
if request.user.is_staff== True:
return render_to_response('staffsettingschange.html', {'form': form})
else:
return render_to_response('settingschange.html', {'form': form})
...
#login_required
def useradd(request):
if request.method == 'POST':
form = UserAddForm(request.POST,request.FILES )
if form.is_valid():
password = request.POST['password']
request.POST['password'] = set_password(password)
form.save()
else:
form = UserAddForm()
return render_to_response('staffadduser.html', {'form':form})
Example of my templates
{% if form.errors %}
<ol>
{% for field in form %}
<H3 class="title">
<p class="error"> {% if field.errors %}<li>{{ field.errors|striptags }}</li>{% endif %}</p>
</H3>
{% endfor %}
</ol>
{% endif %}
<form method="post" id="form" action="" enctype="multipart/form-data" class="infotabs accfrm">
{{ repfrm.as_p }}
<input type="submit" value="Submit" />
</form>
the issue was actually that this line
<form method="post" id="form" action="" enctype="multipart/form-data" class="infotabs accfrm">
appeared as
<form method="post" id="form" action="" enctype="multipart/form
-data" class="infotabs accfrm">
hence the forms were not uploading. And to think I have had this issue for 2 weeks. If its ok with you guys, i will delete this question.
Related
Is there a way for the button to do the following? : When user press the button it takes the user.username of the current user and automatically fill up a form of BookInstance from models.py and save it to the database.
From models.py :
class BookInstance(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
book = models.ForeignKey("Book", on_delete=models.RESTRICT, null=True)
imprint = models.CharField(max_length=200, blank=True, null=True)
due_back = models.DateField(blank=True, null=True)
borrower = models.ForeignKey(
User, on_delete=models.SET_NULL, blank=True, null=True)
LOAN_STATUS = (
('m', 'Maintenance'),
('o', 'On Loan'),
('a', 'Available'),
('r', 'Reserved')
)
status = models.CharField(
max_length=1, choices=LOAN_STATUS, blank=True, default='a')
class Meta:
ordering = ['due_back']
def __str__(self):
return f'{self.id} - {self.book.title}'
def get_absolute_url(self):
return reverse("catalog:book_list")
class Book(models.Model):
title = models.CharField(max_length=50)
author = models.ForeignKey(
'Author', on_delete=models.SET_NULL, null=True)
summary = models.TextField(
max_length=500, help_text="Enter brief description")
isbn = models.CharField('ISBN', max_length=13, unique=True)
genre = models.ManyToManyField(Genre, help_text="Select genre")
language = models.ForeignKey(
"Language", on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("catalog:book_detail", kwargs={"pk": self.pk})
This is my from my views.py :
def borrowBook(request, pk):
context = {
'book_instance': BookInstance.objects.all()
}
success_url = reverse_lazy('catalog:index')
if request.method == "POST":
form = BorrowForm(request.POST or None)
if form.is_valid():
book_instance.id = BookInstance.objects.get(pk=pk)
book_instance.book = BookInstance.objects.get(book=book)
book_instance.borrower = request.user
book_instance.status = 'o'
book_borrowed_count = BookInstance.objects.filter(
owner=request.user).count()
if book_borrowed_count < 4:
book_instance = form.save(commit=False)
book_instance.save()
else:
print("Maximum limit reached!")
return redirect('catalog:index')
return render(request, 'catalog/book_detail.html', {'form': form})
here's from my BorrowForm from forms.py :
class BorrowForm(forms.ModelForm):
class Meta:
model = BookInstance
fields = '__all__'
here's my from my urls.py :
path("book_list/book/<int:pk>/borrow", views.borrowBook, name="borrowBook"),
I also tried using a CBV here:
class BorrowBookView(PermissionRequiredMixin, CreateView):
permission_required = 'login'
model = BookInstance
fields = '__all__'
template_name = 'catalog/borrow_form.html'
success_url = reverse_lazy('catalog:index')
def post(self, request, *args, **kwargs):
book_instance.id = BookInstance.objects.get(pk=pk)
book_instance.book = BookInstance.objects.get(book=book)
book_instance.borrower = request.user
book_instance.status = 'o'
book_instance = form.save(commit=False)
book_instance.save()
CBV path from urls.py :
path("book_list/book/<int:pk>/borrow/",
views.BorrowBookView.as_view(), name="book_borrow"),
Here's how I implemented the button using suggestions from here:
<form action="#" method="post">
{% csrf_token %}
<button
type="submit"
class="btn btn-dark flex-shrink-0 "
value="{{ book.id }}">Borrow
</button>
but when I pressed it doesn't seem to save anything to the database and just popup errors, though I may implemented the button or the function from my is views wrong. Thanks and appreciate for any help provided.
You do not need a Django form for this. Forms are usually used for when you want to create objects or edit its fields (like in the admin page). While here an user is not editing nor creating an object (book), but borrowing one.
So basically, we just need to list all available book instances (status='a'), and have a button to "borrow" it. The borrow action is to update status to 'r' or 'o' and have the borrower updated to the current user which is guaranteed to exist inside the request object by LoginRequiredMixin
views.py
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views import View
from django.contrib import messages
from django.urls import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from .models import BookInstance
class BorrowBook(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs):
book_id = kwargs['pk']
available_books = BookInstance.objects.filter(book__pk=book_id, status='a')
return render(request, 'borrow_book.html', {'available_books': available_books})
def post(self, request, *args , **kwargs):
book_instance_id = request.POST['id']
obj = get_object_or_404(BookInstance, id=book_instance_id)
obj.status = 'r'
obj.borrower = request.user
# Maybe also update due_back data
# obj.due_back = ...
obj.save()
messages.success(request, "Your book is reserved.")
# I used the redirection to the same template
# But you probably want to send the user somewhere else
return HttpResponseRedirect(reverse('core:borrow-book', kwargs={'pk': 1}))
borrow_book.html
{% extends 'base.html' %}
{% block content %}
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% for instance in available_books %}
<form action="{% url 'core:borrow-book' instance.book.id %}" method="POST">
{% csrf_token %}
<input type="hidden" name="id" value="{{instance.id}}">
<p>{{instance.book}}</p>
<p>{{instance.book.language.name}}</p>
<input type="submit" value="Borrow this book.">
</form>
{% endfor %}
{% endblock content %}
urls.py
from django.urls import path
from core import views
app_name = 'core'
urlpatterns = [
path("book_list/book/<int:pk>/borrow/", views.BorrowBook.as_view(), name="borrow-book"),
]
I am working on an Auction website using Django. I am trying to display data of the Last_bid field which is connected to Bid table with a foreign key. I tried many ways but nothing worked out.
The models.py file is:
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.db.models.base import Model
from django.db.models.deletion import CASCADE
from django.db.models.fields import CharField
from django.utils import timezone
class User(AbstractUser):
pass
class Category(models.Model):
category = models.CharField(max_length=64)
def __str__(self):
return f'{self.category}'
class AuctionListing(models.Model):
item_name = models.CharField(max_length=100)
item_image = models.ImageField(upload_to="products", null=True, blank=True)
detail = models.TextField()
price = models.IntegerField()
last_bid = models.ForeignKey('Bid', on_delete=models.CASCADE, blank=True, null=True, related_name='lst')
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='publisher_listing', null=True, blank=True)
watchers = models.ManyToManyField(User, blank=True, related_name='watched_list')
pub_date = models.DateTimeField(auto_now=True, null=True)
deadline = models.DateTimeField(null=True)
list_category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, related_name='sortion')
closed = models.BooleanField(default=False)
def __str__(self):
return f'{self.item_name} - {self.price}'
class Bid(models.Model):
bid = models.IntegerField()
user = models.ForeignKey(User, on_delete=CASCADE)
auction = models.ForeignKey(AuctionListing, on_delete=CASCADE)
bid_date = models.DateTimeField(auto_now=True)
def __str__(self):
return f'{self.bid}-{self.auction}'
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=CASCADE)
com = models.TextField()
pub_date = models.DateField()
com_item = models.ForeignKey(AuctionListing, on_delete=models.CASCADE, related_name='get_comment')
def __str__(self):
return f'{self.user} - {self.pub_date}'
Views.py:
from django.contrib.auth import authenticate, login, logout
# from django.contrib.auth.decorators import login_required
from django.db import IntegrityError, reset_queries
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import redirect, render
from django.urls import reverse
from django.forms import ModelForm
from .models import *
def index(request):
active_list = AuctionListing.objects.all().order_by('id').reverse()
return render(request, "auctions/index.html", {'active_list': active_list })
def login_view(request):
if request.method == "POST":
# Attempt to sign user in
username = request.POST["username"]
password = request.POST["password"]
user = authenticate(request, username=username, password=password)
# Check if authentication successful
if user is not None:
login(request, user)
return HttpResponseRedirect(reverse("index"))
else:
return render(request, "auctions/login.html", {
"message": "Invalid username and/or password."
})
else:
return render(request, "auctions/login.html")
def logout_view(request):
logout(request)
return HttpResponseRedirect(reverse("index"))
def register(request):
if request.method == "POST":
username = request.POST["username"]
email = request.POST["email"]
# Ensure password matches confirmation
password = request.POST["password"]
confirmation = request.POST["confirmation"]
if password != confirmation:
return render(request, "auctions/register.html", {
"message": "Passwords must match."
})
# Attempt to create new user
try:
user = User.objects.create_user(username, email, password)
user.save()
except IntegrityError:
return render(request, "auctions/register.html", {
"message": "Username already taken."
})
login(request, user)
return HttpResponseRedirect(reverse("index"))
else:
return render(request, "auctions/register.html")
class CreateForm(ModelForm):
class Meta:
model = AuctionListing
fields = ['item_name', 'item_image', 'detail', 'price', 'deadline', 'list_category']
def create_listing(request):
user = request.user
if user.id is None:
return redirect('login')
if request.method == 'GET':
context = {
'form': CreateForm()
}
return render(request, 'auctions/create_listing.html', context)
else:
if request.method == 'POST':
form = CreateForm(request.POST or None, request.FILES or None)
if form.is_valid():
item_name = form.cleaned_data['item_name']
item_image = form.cleaned_data['item_image']
detail = form.cleaned_data['detail']
price = form.cleaned_data['price']
deadline = form.cleaned_data['deadline']
list_category = form.cleaned_data['list_category']
listing_created = AuctionListing.objects.create(
item_name = item_name,
item_image = item_image,
detail = detail,
price = price,
deadline = deadline,
list_category = list_category,
user = request.user,
)
listing_created.save()
return redirect('index')
def listing(request, pk):
user = request.user
list = AuctionListing.objects.get(id=pk)
if request.method == 'POST':
bid = request.POST.get('placebid')
user = request.user
form = Bid(bid=bid, user=user, auction=list)
form.save()
return render(request, 'auctions/listing.html', {'list': list})
The index.html is:
{% extends "auctions/layout.html" %}
{% block body %}
<h2>Active Listings</h2>
{% for each in active_list %}
<div class="back">
<div class="imag">
<img src="{{ each.item_image.url }}" alt="">
</div>
<div class="detail">
<h1>{{ each.item_name }}</h1>
<h6>Published by: <span>{{ each.user }}</span></h6>
{% if each.last_bid %}
<p>Current Bid: <span>{{ each.last_bid.bid }} </span></p>
{% else %}
<p>Current Bid: <span>{{ each.price }} </span></p>
{% endif %}
<p>Published date: <span>{{ each.pub_date }}</span></p>
<p>DeadLine: <span>{{ each.deadline }}</span></p>
<div class="bid-detail">
<p>Initial Price: {{ each.price }}</p>
<p>Watchers: 10</p>
</div>
</div>
</div>
{% endfor %}
{% endblock %}
I want to display the last_bid in index.html but I was not able to. Please help me with this problem. I will be thankful to you.
Im trying to let user create a post and select a category, but when it selects a category and I post it, it gives me the error: Exception Value: 'NoneType' object has no attribute 'add'.
If i go to my database, whatever I type, it is save except the category_id which is null.
This is my code
views.py:
#login_required(login_url='login')
def userposts_create_view(request):
form= UserPostForm(request.POST or None)
#print(request.POST)
if request.POST:# form.is_valid():
#data = form.cleaned_data
#print(data)
#categories = data.pop('categories', None)
categories = request.POST['categories']
content = request.POST['content']
title = request.POST['title']
public = False
if 'public' in request.POST and request.POST['public'] == 'on':
public = False
else:
public=True
#print(f"{categories}, {content}, {title}, {public}")
#user_post = UserPost.objects.create(**data, user=request.user)
user_post = UserPost.objects.create(content=content, title=title, public=public, user=request.user)#, categories=categories)
categories = Categories.objects.filter(name=Categories.name)
print(categories)
user_post.categories.get(categories)
return HttpResponseRedirect("/posted/")
context= {'form': form}
return render(request, 'posts/userposts-create-view.html', context)
#list view
#login_required(login_url='login')
def userposts_list_view(request):
allposts= UserPost.objects.all()
context= {'allposts': allposts,
}
return render(request, 'posts/userposts-list-view.html', context)
#detail view
#login_required(login_url='login')
def userposts_detail_view(request, id=None):
post= get_object_or_404(UserPost, id=id)
context= {'post': post,
}
return render(request, 'posts/userposts-detail-view.html', context)
I assume the error must be in the models but not sure...
Models.py
class Categories(models.Model):
name = models.CharField(max_length=100, verbose_name='Nombre')
def __str__(self):
return self.name
User= settings.AUTH_USER_MODEL
class UserPost(models.Model):
user= models.ForeignKey(User, null=False, editable=False, verbose_name='Usuario', on_delete=models.CASCADE)
title= models.CharField(max_length=500, null=False)
content= models.TextField(null=False)
categories = models.ForeignKey(Categories, null=True, blank=True, on_delete=models.CASCADE)
public = models.BooleanField(verbose_name='Privada?',default=True)
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Creado el ')
updated_at = models.DateTimeField(auto_now=True, verbose_name='Actualizado el ')
def __str__(self):
return self.title + ' | ' + str(self.user)
def save(self, *args, **kwargs):
super(UserPost, self).save(*args, **kwargs)
Forms.py
from django import forms
from .models import UserPost
class UserPostForm(forms.ModelForm):
class Meta:
model= UserPost
fields= ["title", "content","categories","public"]
create_view.html
{%extends 'layouts/layout.html'%}
<html>
<head>
<meta charset="UTF-8">
{% block title %}
Post
{% endblock title %}
</head>
<body>
<h1>Create Post</h1>
{% block content %}
<form enctype="multipart/form-data" method="POST" action="">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Post"/>
</form>
{% endblock content %}
urls.py
from django.urls import path
from . import views
from django.conf.urls import url, include
urlpatterns = [
path('articulos/', views.list, name = "list_articles"), #se utilizaria page para el menu
path('categoria/<int:category_id>', views.category, name="category"),
path('articulo/<int:article_id>', views.article, name="article"),
path('create/', views.userposts_create_view, name='create'),
path('posted/', views.userposts_list_view, name='list_view'),
path('posted/<int:id>', views.userposts_detail_view, name='one_posts'),
path('tus_ideas', views.index_page, name='tus_ideas')
]
please try this:
#login_required(login_url='login')
def userposts_create_view(request):
form= UserPostForm(request.POST or None)
if request.POST:
categories = request.POST['categories']
content = request.POST['content']
title = request.POST['title']
public = False
if 'public' in request.POST and request.POST['public'] == 'on':
public = False
else:
public=True
user_post = UserPost.objects.create(content=content, title=title, public=public, user=request.user,categories_id=categories)
return HttpResponseRedirect("/posted/")
context= {'form': form}
return render(request, 'posts/userposts-create-view.html', context)
user_post.categories.add(*categories) would work if categories is a ManyToMany field in your UserPost model whereas it it a ForeignKey in your code.
Change your categories fields to :
class UserPost(models.Model):
...
categories = models.ManyToManyField('Categories', null=True, blank=True)
I'm trying to upload file in a specific folder and store its path in DB through forms(CBV), but it doesn't work!!
this is my code (forms, models, views, template).
I'm selecting the file through forms then I submit the form, but it doesn't submit.
#views.py
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
# fields = ['title', 'content']
success_url = reverse_lazy('blog/new_post.html')
template_name = 'blog/new_post.html'
form_class = PostCreateForm
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect(self.success_url)
else:
return render(request, self.template_name, {'form': form})
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
#model.py
class Post(models.Model):
title = models.CharField(max_length=1000)
content = models.TextField()
xml_file = models.FileField(null=True, upload_to='xml_files')
rate = models.FloatField(null=True, blank=True, default=None)
post_date = models.DateTimeField(default=timezone.now)
post_update = models.DateTimeField(auto_now=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
# return '/detail/{}'.format(self.pk)
return reverse('detail', args=[self.pk])
class Meta:
ordering = ('-post_date', )
#forms.py
class PostCreateForm(forms.ModelForm):
title = forms.CharField( max_length=1000)
content = forms.CharField(widget=forms.Textarea(
attrs={'rows': 15, 'placeholder': 'write here'}
), max_length=50000)
xml_file = forms.FileField(label='upload file')
class Meta:
model = Post
fields = ['title', 'content', 'xml_file', ]
#new_post.html
{% block content %}
{% load crispy_forms_tags %}
<div class="border p-4 mb-5">
<legend class="border-bottom pb-1 mb-3">new post</legend>
<form method="POST">
{% csrf_token %}
{{form|crispy}}
<input class="btn btn-secondary mt-4" type="submit" value="post">
</form>
</div>
{% endblock content %}
When you are uploading media like what you've got, it is necessary to add the following part to your <form>:
enctype=multipart/form-data
thanks for your time:
i've been having a problem on my POST request its getting me de code 302.0
it should create a object that is related to the user that did the request:
views.py:
#login_required
#transaction.atomic
def parceiros_create(request):
if request.method == 'POST':
form = ParceirosForm(request.POST, instance=request.user.parceiros)
if form.is_valid():
form.save()
messages.success(request, ('Parceiro criado'))
return redirect('home2')
else:
messages.error(request, ('Please correct the error below.'))
else:
form = ParceirosForm(instance=request.user)
context = {
'form': form,
}
return render (request, 'parceiroform.html', context)
forms.py:
class ParceirosForm(forms.ModelForm):
nome = forms.CharField(max_length=200)
endereco = forms.TextInput()
responsavel = forms.CharField(max_length=100)
tel = PhoneField(max_length=12)
class Meta:
prefix = 'parceiro'
model = Parceiros
fields = ['nome', 'endereco', 'responsavel', 'tel']
models.py:
get_user_model = User
class Parceiros (models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
nome = models.CharField(max_length=200)
endereco = models.TextField(max_length=400, blank=True)
responsavel = models.CharField(max_length=100)
tel = PhoneField(max_length=12)
created_at = models.DateTimeField(auto_now=True)
updated_at = models.DateTimeField(auto_now_add=True, blank=True)
ativo = models.BooleanField(default=False)
def __str__(self):
return '%s %s' % (self.user, self.nome)
parceiroform.html:
{% extends 'base.html' %}
{% block content %}
<h1>ok</h1>
<h1>OK</h1>
<h1>ok</h1>
<form method="POST">
{% csrf_token %}
{{form.as_p}}
<button type="submit">Save</button>
</form>
{% endblock %}
i'm getting the message (parceiro criado) on my admin although ain't creating any object(Parceiros).
You are not handling the user so change it like this
if form.is_valid():
obj = form.save(commit=False)
obj.user = request.user
obj.save()
....