In a view I have 3 forms:
forms.py
class PostForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(PostForm, self).__init__(*args, **kwargs)
class Meta:
model = Post
fields = ['subtitle', 'latitude', 'longitude', 'tags', 'body']
widgets = {
'body': forms.Textarea(attrs={'class': 'log-body editable'}),
'tags': forms.TextInput(attrs={'id': 'tags-field', 'class': 'log-form-field'}),
'latitude': forms.TextInput(attrs={'id': 'latitude-field', 'class': 'log-form-field'}),
'longitude': forms.TextInput(attrs={'id': 'longitude-field', 'class': 'log-form-field'}),
'subtitle': forms.TextInput(attrs={'id': 'subtitle-field', 'class': 'log-form-field'}),
}
labels = {
'subtitle': 'Subtitle:',
'tags': 'Tags:',
'latitude': 'Latitude',
'longitude': 'Longitude',
'body': ''
}
class ImageForm(forms.ModelForm):
images = forms.ImageField(label='Images', widget=forms.ClearableFileInput(
attrs={
'multiple': True,
'class': 'file-upload',
'id': 'file-upload-button-image',
'name': 'images'}
)
)
class Meta:
model = PostImage
fields = ('images',)
class VideoForm(forms.ModelForm):
videos = forms.FileField(label='Videos', widget=forms.ClearableFileInput(
attrs={
'multiple': True,
'class': 'file-upload',
'id': 'file-upload-button-video',
'name': 'images'
}
)
)
class Meta:
model = PostVideo
fields = ('videos',)
And I have a template that creates a post and stores the videos and pictures and that works great. Where I'm having a hard time is updating a 'Post'.
class PostEditView(TemplateView):
template_name = 'Logging/edit view.html'
post_form_class = PostForm
image_form_class = ImageForm
video_form_class = VideoForm
def get_context_data(self, **kwargs):
context = super(PostEditView, self).get_context_data(**kwargs)
context['post_pk'] = self.kwargs['pk']
context['post_form'] = PostForm(instance=Post.objects.get(pk=self.kwargs['pk']))
context['image_form'] = ImageForm(empty_permitted=True, use_required_attribute=False)
context['video_form'] = VideoForm(empty_permitted=True, use_required_attribute=False)
context['images'] = PostImage.objects.filter(post_id=self.kwargs['pk'])
context['videos'] = PostVideo.objects.filter(post_id=self.kwargs['pk'])
return context
def post(self, request, *args, **kwargs):
context = self.get_context_data()
post_data = request.POST or None
if post_data.get('Delete'):
if len(post_data.getlist('img-index[]')) > 0:
for i in post_data.getlist('img-index[]'):
PostImage.objects.filter(id=i).delete()
if len(post_data.getlist('vid-index[]')) > 0:
for i in post_data.getlist('vid-index[]'):
PostVideo.objects.filter(id=i).delete()
print(post_data)
post_form = PostForm(data=post_data, instance=Post.objects.get(pk=self.kwargs['pk']), prefix='post')
print(post_form.is_bound)
post_form.is_valid()
print(post_form.errors)
images = request.FILES.getlist('image-images')
videos = request.FILES.getlist('video-videos')
if post_form.is_valid():
print('valid form')
for i in images:
instance = PostImage(image=i, post=context['post_pk'])
instance.save()
for v in videos:
instance = PostVideo(video=v, post=context['post_pk'])
instance.save()
return super(PostEditView, self).render_to_response(context)
def form_save(self, form, request):
obj = form.save(commit=False)
obj.user = request.user
obj.author = request.user.first_name + ' ' + request.user.last_name
obj.event_type = 'Log Entry'
obj.save()
messages.success(self.request, "{} posted successfully".format(obj))
return obj
When I call is_valid() on post_form it always says false, although it does say its bound. My post object does contain the data from the form in my template, including a csrf token, but for some reason the form is never valid and says that all the fields are empty.
from print(post_data):
<QueryDict: {'csrfmiddlewaretoken': ['h5uxuACKsvBcO4lrPB7yKbYgr0BsASEklT3GTp6R3t8na13TadAfjbihl2VyGvdC'], 'subtitle': ['Test with photos'], 'latitude': ['48.000'], 'longitude': ['112.000'], 'tags': ['[]'], 'images': [''], 'videos': [''], 'body': ['<p>body test 2 saa</p>']}>
from print(post_form.is_bound):
True
from print(post_form.errors):
<ul class="errorlist">
<li>subtitle<ul class="errorlist"><li>This field is required.</li></ul></li><li>latitude
<ul class="errorlist"><li>This field is required.</li></ul></li><li>longitude
<ul class="errorlist"><li>This field is required.</li></ul></li><li>tags
<ul class="errorlist"><li>This field is required.</li
></ul></li><li>body
<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
Models.py
class Post(models.Model):
class Status(models.TextChoices):
active = 'Active'
inactive = 'Inactive'
user = models.ForeignKey(Account, on_delete=models.CASCADE)
author = models.CharField(max_length=255)
title = models.CharField(max_length=80, default='Log Entry: ' + datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S"))
subtitle = models.CharField(max_length=255)
latitude = models.DecimalField(decimal_places=3, max_digits=6)
longitude = models.DecimalField(decimal_places=3, max_digits=6)
post_time = models.DateTimeField(auto_now_add=True)
tags = TaggableManager()
body = models.TextField()
history = HistoricalRecords()
event_type = models.CharField(max_length=50, choices=EventType.choices, default='Log Entry', editable=False)
status = models.CharField(max_length=10, choices=Status.choices, default='Active')
def __str__(self):
return 'Post by: ' + str(self.user) + " on: " + self.post_time.strftime("%m/%d/%Y at %H:%M:%S")
def get_image_filename(instance, filename):
title = instance.post.title
slug = slugify(title)
return "post_media/%s/%s" % (slug, filename)
class PostImage(models.Model):
post = models.ForeignKey(Post, default=None, on_delete=models.PROTECT)
image = models.ImageField(upload_to=get_image_filename, verbose_name='Image')
def filename(self):
return self.image.name.split('/')[-1]
class PostVideo(models.Model):
post = models.ForeignKey(Post, default=None, on_delete=models.PROTECT)
video = models.FileField(upload_to=get_image_filename, verbose_name='Video')
def filename(self):
return self.video.name.split('/')[-1]
template:
{% extends 'layout/base.html' %}
{% load static %}
{% block titleblock %}New Log{% endblock %}
{% block header %}
<script src="{% static 'Logging/js/medium-editor.min.js' %}"></script>
<link rel="stylesheet" href="{% static 'Logging/css/medium-editor.min.css' %}">
<link rel="stylesheet" href="{% static 'Logging/css/new_post.css' %}">
{% endblock %}
{% block bodyblock %}
<form class="post-form" id="post-form" enctype="multipart/form-data" method="POST" action=".">
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="Modal-title" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Confirm</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Are you sure you want to delete these items?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-danger" name="Delete" value="1" form="post-form">Delete</button>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-10 col-sm-12">
{% csrf_token %}
{% for field in post_form %}
{% ifnotequal field.label '' %}
<div class="input">
{{ field.label_tag }}
{{ field }}
</div>
<br>
{% endifnotequal %}
{% endfor %}
</div>
<div class="col-lg-2 col-sm-12 button-col">
<label for="file-upload-button-image" class="custom-file-upload">
<div class="upload-button-wrapper">
{{ image_form.images }}
<p id="image-num"></p>
<img src="{% static 'layout/img/image.svg' %}" alt="svg" id="img-svg">
<img src="{% static 'layout/img/plus-circle.svg' %}" alt="svg+" id="plus-svg">
</div></label>
<label for="file-upload-button-video" class="custom-file-upload">
<div class="upload-button-wrapper">
{{ video_form.videos }}
<p id="video-num"></p>
<img src="{% static 'layout/img/film.svg' %}" alt="svg" id="img-svg">
<img src="{% static 'layout/img/plus-circle.svg' %}" alt="svg+" id="plus-svg">
</div></label>
</div>
</div>
<div class="row">
<div class="col-lg-4 col-md-6 col-sm-12 edit-col">
<div class="images_existing">
{% for image in images %}
<div class="stacker">
<div class="image-selector-wrapper">
<input type="checkbox" id="" name="img-index[]" class="invisible img-checkboxes" value="{{ image.pk }}">
<img class="thumbnail" src="{{ image.image.url }}" alt="{{ image.filename }}">
<h6>{{ image.filename }}</h6>
{% if forloop.first %}
<div class="num-indicator" id="image-number"></div>
{% endif %}
</div>
</div>
{% endfor %}
<div class="button-box">
<button type="submit" name="download" value="1" class="btn-primary">Download</button>
<button type="button" class="btn-danger" data-toggle="modal" data-target="#deleteModal">Delete</button>
</div>
</div><div class="edit" id="edit-images">Edit</div>
</div>
<div class="col-lg-4 col-md-6 col-sm-12 edit-col">
<div class="videos_existing">
{% for video in videos %}
<div class="stacker">
<div class="video-selector-wrapper">
<input type="checkbox" id="" name="vid-index[]" value="{{ video.pk }}" class="invisible video-cb">
<img class="thumbnail-video" src="{% static 'layout/img/film.svg' %}" alt="{{ video.filename }}">
<h6>{{ video.filename }}</h6>
{% if forloop.first %}
<div class="num-indicator" id="video-number"></div>
{% endif %}
</div></div>
{% endfor %}
</div><div class="edit" id="edit-video">Edit</div>
</div></div>
<div class="row">
<div class="col">
{{ post_form.body }}
<button type="submit" class="custom-submit-button"><img src="{% static 'layout/img/upload.svg' %}" alt="submit"> <span>Submit</span></button>
</div>
</div>
{% if post_form.errors %}
{% for field in post_form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in post_form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
</form>
<script>var editor = new MediumEditor('.editable');</script>
<script src="{% static 'Logging/js/new_post.js' %}"></script>
{% endblock %}
I can not for the life of my figure this out. Any help would be appreciated!
Related
I want to assign a task to one of the users who commented on the post. But when I try to go on post_detail.html an error occurs, and i.e.
OperationalError at /home/
no such column: home_post.assign_to_id
PS: I have done python manage.py makemigrations and python manage.py migrate
So, here is the code snippet. I can give more information if needed. Thanks in advance!
views.py
def SaveAssigned(request):
if request.method == "POST":
if request.POST.get('assigned'):
savevalue = Post()
savevalue.assign_to = request.POST.get('assigned')
savevalue.save()
return render(request, 'post_detail.html')
else:
return render(request, 'post_detail.html')
class PostDetailView(DetailView):
model = Post
# template_name = 'home/post_detail.html'
def get_context_data(self, *args, **kwargs):
post_available = get_object_or_404(Post, id=self.kwargs['pk'])
cat_menu = Category.objects.all()
context = super(PostDetailView, self).get_context_data()
context["cat_menu"] = cat_menu
return context
urls.py
urlpatterns = [
path('', PostListView.as_view(), name='home'),
path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'),
path('post/new/', PostCreateView.as_view(), name='post-create'),
path('post/<int:pk>/update/', PostUpdateView.as_view(), name='post-update'),
path('post/<int:pk>/delete/', PostDeleteView.as_view(), name='post-delete'),
path('post/<int:pk>/comment/', AddCommentView.as_view(), name='add-comment'),
path('add_category/', AddCategoryView.as_view(), name='add-category'),
path('category/<str:cats>/', CategoryView, name='category'),
path('category-list/', CategoryListView, name='category-list'),
]
models.py
class Post(models.Model):
title = models.CharField(max_length = 100)
snippet = models.CharField(max_length= 200)
content = RichTextField(blank=True, null=True)
date_posted = models.DateTimeField(default = timezone.now)
author = models.ForeignKey(User, on_delete= models.CASCADE)
category = models.CharField(max_length=255, default='Coding')
assign_to = models.ForeignKey(User,related_name='assign_to', on_delete=models.CASCADE, null=True)
def __str__(self):
return self.title + ' | ' + str(self.author)
def get_absolute_url(self):
return reverse('home')
post_detail.html
{% extends 'users/base.html' %}
{% block body %}
<article class="media content-section">
<img class="rounded-circle article-img" src="{{ object.author.profile.image.url }}">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="#">{{ object.author }}</a>
<small class="text-muted">{{ object.category }}</small>
<small class="text-muted" style="float: right;">{{ object.date_posted|date:"F d, Y" }}</small>
</div>
<h2 class="article-title">{{ object.title }}</h2>
<p class="article-content">{{ object.content|safe }}</p>
</div>
</article>
{% if object.author == user %}
<div>
<a class="btn btn-outline-secondary bt-sm mt-1 mb-1" href="{% url 'post-update' object.id %}">Update</a>
<a class="btn btn-outline-danger bt-sm mt-1 mb-1" href="{% url 'post-delete' object.id %}">Delete</a>
<a class="btn btn-outline-primary bt-sm mt-1 mb-1" style="float: right;" href="">Done</a>
</div>
<form method="POST">
{% csrf_token %}
<select name="assigned">
<option selected disabled="true"> Select User</option>
{% if not post.comments.all %}
<option>NA</option>
{% else %}
{% for comment in post.comments.all %}
<option>{{ comment.author }}</option>
{% endfor %}
{% endif %}
</select>
<input type="submit" value="Assign" name="">
</form>
{% endif %}
<br>
<hr>
<h2>Comment Section</h2>
<br>
{% if not post.comments.all %}
No Comments yet
<br>
Be the first Ont to Comment!
{% else %}
Add a comment
<br>
{% for comment in post.comments.all %}
<strong>
{{ comment.author }} - {{ comment.date_added }}
</strong>
<br>
{{ comment.body }}
<br><br>
{% endfor %}
<hr>
{% endif %}
<br><br>
{% endblock %}
This error occurs when your model does not contain the specific column and you are trying to add the value in that model with a specific column name.
You can solve this by following steps -
Step - 1. python manage.py makemigration
Step - 2. python manage.py migrate
I have tried to submit a comment from app rather than django admin. Comment is not displaying when submitted from my created app. But it is displaying when I add a comment from django admin app. May be I am doing something wrong in views.py file. Can anyone help me on this? Thank you.
views.py:
#login_required
def book_review(request,id):
book = get_object_or_404(Bookslist, id=id)
comment=Comment.objects.all().filter(post_id=id)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.user_id = request.user
post.message= comment
post.save()
return redirect('book_review', id=id)
else:
form=CommentForm()
return render(request, "books/book_review.html", {'book':book, 'comment':comment, 'form': form})
models.py:
class Comment(models.Model):
message= models.TextField('Message',null=True)
date_comment=models.DateTimeField(default=now, null=True)
user_id= models.ForeignKey(User, on_delete=models.CASCADE,null=True)
post_id=models.ForeignKey(Bookslist,on_delete=models.CASCADE,null=True)
forms.py:
from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['message', ]
book_review.html:
{% extends 'books/base.html' %}
{% load static %}
{% block stylesheet %}
<link rel="stylesheet" href="{% static 'accounts/accounts.css' %}">
{% endblock %}
{% block content %}
<div class = "container">
<ul class = "nav nav-tabs" id = "myTab" role = "tablist">
<li class = "nav-item">
<a class = "nav-link active" id = "summary-tab" data-toggle = "tab"
href = "#summary" role = "tab" aria-controls = "summary"
aria-selected = "true">Summary</a>
</li>
<li class = "nav-item">
<a class = "nav-link" id = "characters-tab" data-toggle = "tab"
href = "#characters" role = "tab" aria-controls = "characters"
aria-selected = "false">Characters</a>
</li>
<li class = "nav-item">
<a class = "nav-link" id = "relatedbooks-tab" data-toggle = "tab"
href = "#relatedbooks" role = "tab" aria-controls = "relatedbooks"
aria-selected = "false">Related Books</a>
</li>
</ul>
<div class = "tab-content" id = "myTabContent">
<div class = "tab-pane fade show active" id = "summary" role = "tabpanel"
aria-labelledby = "summary-tab"><br><br>
{{book.summary}}
</div>
<div class = "tab-pane fade" id = "characters" role = "tabpanel"
aria-labelledby = "characters-tab"><br><br>
{{book.c1}}<br><br>{{book.c2}}<br><br>{{book.c3}}<br><br>{{book.c4}}<br><br>{{book.c5}}<br><br>
{{book.c6}}<br><br>{{book.c7}}<br><br>{{book.c8}}<br><br>{{book.c9}}<br><br>
{{book.c10}}
</div>
<div class = "tab-pane fade" id = "relatedbooks" role = "tabpanel"
aria-labelledby = "relatedbooks-tab">Content for related books tab</div>
</div>
<br>
<br>
<div class="container">
<form method="post" class="mb-4">
{% csrf_token %}
<div class="form-group">
<label for="exampleFormControlTextarea1">Leave your comment:</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-success">Post</button>
</form>
{% for com in comment %}
<div class="card mb-2">
<div class="card-body p-3">
<div class="row">
<div class="col-2">
<img src="{% static 'images/icon2.webp' %}" alt="{{ com.user_id }}" class="w-100">
<small>Posts: {{ com.count }}</small></div>
<div class="col-10">
<div class="row mb-3">
<div class="col-6">
<strong class="text-muted">{{ com.user_id }}</strong>
</div>
<div class="col-6 text-right">
<small class="text-muted">{{ com.date_comment }}</small>
</div>
</div>
{{ com.message }}<br><br>
{% if com.user_id == user %}
<button type="button" class="btn btn-primary">Reply</button>
{% endif %}
</div>
</div></div></div></div>
{% endfor %}
</div>
</div>
</div>
<!-- jQuery library -->
<script src = "https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity = "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin = "anonymous">
</script>
<!-- Popper -->
<script src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity = "sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin = "anonymous">
</script>
<!-- Latest compiled and minified Bootstrap JavaScript -->
<script src = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity = "sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous">
</script>
{% endblock %}
You need to add the post_id to the newly created comment.
Like so:
post.post_id = id
Also make sure you are using the correct naming for your variables i believe post should be comment in this scenario based on the form being of CommentForm: model = Comment
This replacement would make for sense for the code:
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.user_id = request.user
comment.message= comment
comment.post_id = id
comment.save()
I've been working on a project lately and got the above error. It says " Error during template rendering".I have a similar model, which works perfectly fine. I've looked for similar errors but got none matching my situation. I don't know where I went wrong. It would be great if I get helpful answers.
Models.py
class ServiceTax(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE,related_name="service_tax",null=True,blank=True)
name=models.CharField(max_length=100)
percent=models.FloatField(default='0')
add_amount=models.IntegerField(default='0')
def __str__(self):
return self.name
Forms.py
class ServiceTaxForm(forms.ModelForm):
class Meta:
model = ServiceTax
fields = "__all__"
widgets = {
'name' : forms.TextInput(attrs={'class': 'form-control'}),
'percent' : forms.NumberInput(attrs={'class': 'form-control','step':'0.01'}),
'add_amount' : forms.NumberInput(attrs={'class':'form-control','maxlength':5}),
}
labels={
'add_amount': "Additional Amount"
}
Views.py
def tax_form(request,id=0):
if request.method == 'GET':
if id == 0:
form = ServiceTaxForm(request)
else:
tax = ServiceTax.objects.get(pk=id)
if tax in request.user.service_tax.all():
form = ServiceTaxForm(request,instance=tax)
else:
return redirect('/revenue/tax')
return render(request,'tax-form.html',{'form':form})
else:
if id==0:
form = ServiceTaxForm(request,request.POST)
if form.is_valid():
name = form.cleaned_data["name"]
percent = form.cleaned_data["percent"]
add_amount = form.cleaned_data["add_amount"]
t = AnnualTax(
name=name,
percent=percent,
add_amount=add_amount,
)
t.save()
request.user.service_tax.add(t)
else:
tax = ServiceTax.objects.get(pk=id)
if tax in request.user.service_tax.all():
form = ServiceTaxForm(request,request.POST,instance=tax)
if form.is_valid():
name = form.cleaned_data["name"]
percent = form.cleaned_data["percent"]
add_amount = form.cleaned_data["add_amount"]
tax_obj = ServiceTax.objects.get(pk=id)
tax_obj.name = name
tax_obj.percent = percent
tax_obj.add_amount = add_amount
tax_obj.save()
return redirect('/revenue/tax')
tax-form.html
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<i class="fa fa-chevron-circle-left fa-3x m-2"></i>
<div class="content">
<div class="container-fluid">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">Add Service Tax</h4>
</div>
<div class="card-body">
<form action="" method="POST" autocomplete="off">
{% csrf_token %}
<div class="row">
<div class="col-md-4 pr-1">
<div class="form-group">
{{ form.name | as_crispy_field}}
</div>
</div>
<div class="col-md-4 pr-1">
<div class="form-group">
{{ form.percent | as_crispy_field}}
</div>
</div>
<div class="col-md-4 pr-1">
<div class="form-group">
{{ form.add_amount | as_crispy_field}}
</div>
</div>
</div>
<button type="submit" class="btn btn-success btn-fill pull-right">
{% if request.get_full_path == '/income/tax/add/' %}
Add Tax
{% else %}
Update
{% endif %}
</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
You should retrieve your forms passing request.METHOD, not just request
As an example this piece of code form = ServiceTaxForm(request) should be form = ServiceTaxForm(request.POST)
How do I add pagination to this form's search functionality?
By default, on page refresh, the HTML template for loop shows all the results for all the courses. When the user types in criteria into the form, the form filters the course results template for loop based on what the user typed. Is there a way on page refresh to show only a set limit of course results on the page instead of all of them? Then when a user searches/filters, that pagination limit of X number of course results on a page will still need to show but still applied to the search criteria/filter.
HTML:
<form id='courseform' action="." method="get">
<div class="form-row">
<div class="form-group col-12"> {{ form.title__icontains }} </div>
<div class="form-group col-md-2 col-lg-2"> {{ form.visited_times__gte.label_tag }} {{ form.visited_times__gte }} </div>
<div class="form-group col-md-2 col-lg-2"> {{ form.visited_times__lte.label_tag }} {{ form.visited_times__lte }} </div>
<div class="form-group col-md-2 col-lg-2"> {{ form.created_at__gte.label_tag }} {{ form.created_at__gte }} </div>
<div class="form-group col-md-2 col-lg-2"> {{ form.created_at__lte.label_tag }} {{ form.created_at__lte }} </div>
<div class="form-group col-md-2"> {{ form.skill_level.label_tag }} {{ form.skill_level }} </div>
<div class="form-group col-md-2"> {{ form.subjects.label_tag }} {{ form.subjects }} </div>
</div>
<script src='https://www.google.com/recaptcha/api.js?render=6LeHe74UAAAAAKRm-ERR_fi2-5Vik-uaynfXzg8N'></script>
<div class="g-recaptcha" data-sitekey="6LeHe74UAAAAAKRm-ERR_fi2-5Vik-uaynfXzg8N"></div>
<button type="submit" class="btn btn-primary form-control">Search</button>
<p>This site is protected by reCAPTCHA and the Google
<a target="_blank" rel="noopener noreferrer" href="https://policies.google.com/privacy">Privacy Policy</a> and
<a target="_blank" rel="noopener noreferrer" href="https://policies.google.com/terms">Terms of Service</a> apply.
</p>
</form>
<!--Used to have {{ object.subjects }} next to -->
{% for object in object_list %}
<a class="course_list_link" href="{{ object.get_absolute_url }}"> <p class = "course_list_border"> <strong> {{ object }} </strong> <br/> <br/> {{ object.description }} <br/><br/> {{ object.skill_level }} {{ object.created_at }} Views: {{ object.visited_times }}
{% for sub in object.subjects.all %}
{{ sub.name }}
{% endfor %} </p> </a>
{% endfor %}
Views.py:
class CourseListView(ListView):
template_name = 'courses/course_list.html'
def get_queryset(self):
return Course.objects.all()
def get(self, request, *args, **kwargs):
form = CourseForm(request.GET)
queryset = self.get_queryset()
if form.is_valid():
queryset = queryset.filter(**{k: v for k, v in form.cleaned_data.items() if v})
self.object_list = queryset
return self.render_to_response(self.get_context_data(form=form,object_list=queryset,))
Forms.py:
class CourseForm(forms.Form):
title__icontains = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control col-12', 'autocomplete':'off', 'id':'title_contains', 'type':'search', 'placeholder': 'Course Name'}), required=False)
visited_times__gte = forms.IntegerField(widget=forms.NumberInput(attrs={'class':'form-control', 'autocomplete':'off','id':'view_count_max', 'type':'number', 'min':'0', 'placeholder': '0'}), required=False, validators=[MinValueValidator(0), MaxValueValidator(99999999999999999999999999999999999)])
visited_times__lte = forms.IntegerField(widget=forms.NumberInput(attrs={'class':'form-control', 'autocomplete':'off', 'id':'view_count_min', 'type':'number', 'min':'0', 'placeholder': '1000000'}), required=False, validators=[MinValueValidator(0), MaxValueValidator(99999999999999999999999999999999999)])
created_at__gte = forms.DateField(widget=forms.TextInput(attrs={'class':'form-control', 'autocomplete':'off', 'id':'date_max','type':'date', 'placeholder': 'mm/dd/yyy'}), required=False)
created_at__lte = forms.DateField(widget=forms.TextInput(attrs={'class':'form-control', 'autocomplete':'off', 'id':'date_min', 'type':'date', 'placeholder': 'mm/dd/yyy'}), required=False)
skill_level = forms.ChoiceField(widget=forms.Select(attrs={'class':'form-control', 'autocomplete':'off','id':'skill_level'}), choices = ([('',''), ('Beginner','Beginner'), ('Intermediate','Intermediate'),('Advanced','Advanced'), ]), required=False)
subjects = forms.ModelChoiceField(queryset=Subject.objects.all().order_by('name'), empty_label="", widget=forms.Select(attrs={'class':'form-control', 'autocomplete':'off', 'id':'subjects'}), required=False)
# the new bit we're adding
def __init__(self, *args, **kwargs):
super(CourseForm, self).__init__(*args, **kwargs)
self.fields['title__icontains'].label = "Course Name:"
self.fields['visited_times__gte'].label = "Min Views:"
self.fields['visited_times__lte'].label = "Max Views:"
self.fields['created_at__gte'].label = "Min Date:"
self.fields['created_at__lte'].label = "Max Date:"
self.fields['skill_level'].label = "Skill Level:"
self.fields['subjects'].label = "Subject:"
self.fields['subjects'].queryset = Subject.objects.filter()
Models.py:
class Subject(models.Model):
SUBJECT_CHOICES = ()
name = models.CharField(max_length=20,choices=SUBJECT_CHOICES)
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
class Course(models.Model):
SKILL_LEVEL_CHOICES = (
('Beginner', 'Beginner'),
('Intermediate', 'Intermediate'),
('Advanced', 'Advanced'),
)
slug = models.SlugField()
title = models.CharField(max_length=120)
description = models.TextField()
allowed_memberships = models.ManyToManyField(Membership)
created_at = models.DateTimeField(auto_now_add=True)
subjects = models.ManyToManyField(Subject)
skill_level = models.CharField(max_length=20,choices=SKILL_LEVEL_CHOICES, null=True)
visited_times = models.PositiveIntegerField(default=0)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('courses:detail', kwargs={'slug': self.slug})
#property
def lessons(self):
return self.lesson_set.all().order_by('position')
class Meta:
ordering = ('title',)
I tried following some tutorials Django docs one but not sure how to embed that pagination code to mine.
https://docs.djangoproject.com/en/3.0/topics/pagination/
I would appreciate if anyone could help me with this.
Please edit to include your code.
In the page you linked to, read this section:
https://docs.djangoproject.com/en/3.0/topics/pagination/#paginating-a-listview
You just need to add this to your ListView
paginate_by = N
then add
<div class="pagination">
<span class="step-links">
{% if contacts.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
</span>
{% if contacts.has_next %}
next
last »
{% endif %}
</span>
</div>
to course_list.html.
Serach form (html) :
<!-- Search Form -->
<form class="navbar-search navbar-search-dark form-inline mr-3 d-none d-md-flex ml-lg-auto" action="{% url 'search' %}" method="get">
<div class="form-group mb-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search Tasks" aria-label="Search" name="q">
<button class="btn btn-outline-white my-2 my-sm-0" type="submit">Search</button>
</div>
</form>
views.py
class SearchView(ListView): # taskları arama sonucu listeliyoruz
model = Task
template_name = 'task/search.html'
paginate_by = 5
context_object_name = 'task'
def get_queryset(self):
query = self.request.GET.get("q")
if query:
return Task.objects.filter(
Q(title__icontains=query) | Q(content__icontains=query) | Q(tag__title__icontains=query)).order_by(
'id').distinct()
return Task.objects.all().order_by('id')
In whichever field you want to use pagination, write the code there (example category_detail.html) :
<div class="card-footer py-4">
{% if is_paginated %}
<nav aria-label="...">
<ul class="pagination justify-content-end mb-0">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}" tabindex="-1">
<i class="fas fa-angle-left"></i>
<span class="sr-only">Previous</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">
<i class="fas fa-angle-left"></i>
<span class="sr-only">Previous</span>
</a>
</li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="page-item active">
<a class="page-link" href="#"> {{ i }} </a>
</li>
{% else %}
<li class="page-item">
<a class="page-link" href="?page={{ i }}">{{ i }}<span class="sr-only">(current)</span></a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}">
<i class="fas fa-angle-right"></i>
<span class="sr-only">Next</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#">
<i class="fas fa-angle-right"></i>
<span class="sr-only">Next</span>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
</div>
I hope the examples worked for you.
For some reason I cannot get my images to upload with Django. The models are saving the filename but saving the file in my media folder.
This is my Model
class Quiz(models.Model):
name = models.CharField(
verbose_name ='Quiz Title',
max_length = 50
)
description = models.TextField(
blank = True,
null = True,
verbose_name = 'Quiz Description'
)
pool = models.ForeignKey (
Pool,
verbose_name = 'Category of Quiz',
)
categories = models.ManyToManyField (
Category,
through = 'QuizCategory',
related_name = 'category',
verbose_name = 'Category',
help_text = 'Categories in this Quiz'
)
live = models.BooleanField (
verbose_name = 'Quiz is Live?',
default = False,
)
logo = models.ImageField(
upload_to = 'logos',
blank = True,
)
def __unicode__(self):
return u'%s' % (self.name)
This is my AMENDED View
def create_quiz(request):
if request.method == "POST":
form = QuizForm(request.POST, request.FILES)
if form.is_valid():
# file is saved
form.save()
EDIT
And this is FORM declaration
class QuizForm (forms.ModelForm):
class Meta:
model = Quiz
fields = ('name', 'description', 'pool', 'categories', 'live', 'logo')
HTML
<form method="post" action="{% url 'create-quiz' %}" enctype="multipart/form-data" >{% csrf_token %}
<input hidden name="id" value="{% if quiz.id %}{{quiz.id}}{% else %}0{% endif %}" readonly>
<div class="col-xs-12 col-sm-8 col-md-6 col-md-offset-2">
<input required type="text" name="name" {% if quiz.name %}value="{{quiz.name}}"{% else %}placeholder="Quiz Name"{% endif %} class="form-control quiz-search-box">
<textarea required name="description" {% if quiz.description %}{% else %}placeholder="Quiz Description"{% endif %} class="form-control quiz-search-box">{% if quiz.description %}{{quiz.description}}{% endif %}</textarea>
<select name="pool" class="form-control quiz-search-box">
{% for p in pool %}<option value="{{p.name}}" {% if quiz.pool.name == p.name %}selected{% endif %}>{{p.name}}</option>{% endfor %}
</select>
<h2>Questions</h2>
<table class="table table-condenced">
{% for q in questions %}
<tr><td>{{q.name}}</td></tr>
{% endfor %}
{% if quiz != 'new' %}
<a data-toggle='modal' data-target='#myQuestionModal' class="btn btn-primary">Add Question</a>
{% endif %}
</table>
</div>
<div class="col-xs-12 col-sm-4 col-md-2 ">
<span class="number-of-questions">
Number of questions in this quiz: {{questions|length}}
</span>
<span class="add-quiz-logo">
{% if quiz.logo %}
<img id="logo" src="/media/{{quiz.logo}}" width="150" alt="Logo spacer" />
{% else %}
<img id="logo" src="{% static '/img/no-logo.png' %}" width="150" alt="Logo spacer" />
{% endif %}
<input id="id_image" type="file" class="" name="logo" onchange="readURL(this);">
</span>
<div>
<input type="submit" value="Save Quiz" class="btn btn-primary" />
</div>
</div>
</form>
Help most welcome. Thank you
Instead of POST:
quiz.pool = Pool.objects.get(name=request.POST.get('pool'))
Try to use FILES:
quiz.pool = Pool.objects.get(name=request.FILES.get('pool'))
UPDATE:
Also you should to set up django to work with media files.
Add to settings:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'media')
and include media to urlpattern:
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
After this you can insert image into your template with this:
<img src="{{ instance.logo.url }}"/>
Dr Mouse solved this. I forgot enctype="multipart/form-data" in the <form>