I'm trying to call my comment form from the blog page, but it just keeps refreshing the particular blog page. Here's my code;
models.py
class BlogPost(models.Model):
# id = models.IntegerField()
user = models.ForeignKey(User, default=1, null=True, on_delete=models.SET_NULL)
image = models.ImageField(upload_to='image/', blank=True, null=True)
title = models.CharField(max_length=120)
slug = models.SlugField(unique=True)
content = models.TextField(null=True, blank=True)
publish_date = models.DateTimeField(auto_now=False, auto_now_add=False, null=True, blank=True)
timestamp = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
objects = BlogPostManager()
class Meta:
ordering = ['-publish_date', '-updated', '-timestamp']
def __str__(self):
return self.title
def get_absolute_url(self):
return f"/blog/{self.slug}"
def get_edit_url(self):
return f"{self.get_absolute_url()}/edit"
def get_delete_url(self):
return f"{self.get_absolute_url()}/delete"
class Comment(models.Model):
comment_cont = models.TextField(max_length=200, verbose_name='Comment content')
user_name = models.ForeignKey(User, default=1, null=True, on_delete=models.SET_NULL)
comment_post = models.ForeignKey(BlogPost, on_delete=models.CASCADE, related_name='comments')
comment_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.comment_cont
def get_absolute_url(self):
return f"{BlogPost.get_absolute_url()}"
def get_add_url(self):
return f"{self.get_absolute_url()}/addc"
views.py
def add_comment_to_post(request, slug):
post = get_object_or_404(BlogPost, slug=slug)
if request.method == "POST":
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.save()
return redirect('blog_post_detail_view', slug=post.slug)
else:
form = CommentForm()
template_name = 'formc.html'
context = {"title": f"New comment on {post.title}", "form": form}
return render(request, template_name, context)
urls.py
path('<str:slug>/addc', add_comment_to_post),
formc.html
<form method='POST' action='.' enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Comment</button>
</form>
button in home.html
<a class="btn btn-primary" href="{{ comments.get_add_url }}">Add Comment...</a>
I know the href for the button isn't right, but I can't figure out how to make it call the comment form. Please, I need help. Thanks.
I figured out what the href could be. I kinda feel like I was purposefully left to figure this one out on my own lol.
Please let me know if there's a better way I could do this. Thanks!!
home.html
<a class="btn btn-primary" href="/{{blog_post.slug}}/addc/">Add Comment...</a>
Related
All I want to do is add time widget to my form so I can easily pick the time. Everything is very simple, the page is loading but the widgets don't show up. No error nothing. I am thinking maybe I didn't set up the form widgets correctly but not sure what I did wrong. Here is my Forms.py-
from django.contrib.admin import widgets
from django.contrib.admin.widgets import AdminDateWidget, AdminTimeWidget, AdminSplitDateTime
class WorkOutForm(ModelForm):
class Meta:
model = WorkOut
fields = '__all__'
widgets={
'start':AdminTimeWidget(),
'end':AdminTimeWidget(),
}
Here is the Models.py. You will notice "start" and "end" fields are timefield-
class WorkOut(models.Model):
date=models.DateField(auto_now_add=True, auto_now=False, blank=True)
day=models.DateField(auto_now_add=True, auto_now=False, blank=True)
start=models.TimeField(null=True)
name=models.CharField(max_length=100, choices=move)
weight=models.CharField(max_length=100, blank=True)
rep=models.CharField(max_length=100, blank=True)
pedal= models.CharField(max_length=100, blank=True)
stretchtype =models.CharField(max_length=100, blank=True)
end=models.TimeField(null=True)
note=models.TextField(max_length=300, blank=True)
def __str__(self):
return self.name
And here are the views linked to it even though I don't think it has much relevance-
def workout(request):
form=WorkOutForm()
if request.method=="POST":
form=WorkOutForm(request.POST)
if form.is_valid():
form.save()
context={'form':form}
return render(request, 'myapp/enter_workout.html', context)
def update_workout(request, pk):
order=WorkOut.objects.get(id=pk)
form=WorkOutForm(instance=order)
if request.method=='POST':
form=WorkOutForm(request.POST, instance=order)
if form.is_valid():
form.save()
context={'form':form}
return render(request, 'myapp/enter_workout.html', context)
And the form on HTML page is also very basic,so don't think there is any issue there either-
<form action="" method="POST">
{% csrf_token %}
{{form}}
<input type="submit" value="Submit">
</form>
What have I done wrong here? How can I make those widgets to show up?
You can try to fill the default values with the current time.
from datetime import datetime
class WorkOut(models.Model):
move = (("1", "Tom"), ("2", "Sara"), ("3", "Emilia"),)
date = models.DateField(auto_now_add=True, auto_now=False, blank=True)
day = models.DateField(auto_now_add=True, auto_now=False, blank=True)
start = models.TimeField(default=datetime.now, null=True)
name = models.CharField(max_length=100, choices=move)
weight = models.CharField(max_length=100, blank=True)
rep = models.CharField(max_length=100, blank=True)
pedal = models.CharField(max_length=100, blank=True)
stretchtype = models.CharField(max_length=100, blank=True)
end = models.TimeField(default=datetime.now,null=True)
note = models.TextField(max_length=300, blank=True)
def __str__(self):
return self.name
Update 22.10.2022
Made fields with time selection on bootstrap.
For this you need to install:
pip install django-bootstrap4
pip install django-bootstrap-datepicker-plus
In the WorkOutForm class in init set the styles for all fields.
forms.py
from bootstrap_datepicker_plus.widgets import TimePickerInput
class WorkOutForm(ModelForm):
class Meta:
model = WorkOut
fields = "__all__"
widgets = {
"start": TimePickerInput(),
"end": TimePickerInput(),
}
def __init__(self, *args, **kwargs):
super(WorkOutForm, self).__init__(*args, **kwargs)
for field in iter(self.fields):
self.fields[field].widget.attrs.update({
"class": "form-control"
})
templates
{% load bootstrap4 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}
{{ form.media }}
<form action="" method="POST" style="width: 20%">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
I have looked for an answer and all I can find are answers related to forms. I haven't seen anything related to a model object. I have a model called PanelType and I am trying to loop through every object to display relevant information pertaining to each panel type on a html template. I have created 3 PanelType objects through the admin page, so there is not "None". I believe I have this setup correctly but it's returning an error of returning None objects. I'd appreciate any help.
models.py
class PanelType(models.Model):
name = models.CharField('Name', max_length=150, default='')
slug = models.SlugField(unique=True)
description = models.TextField('Description', null=True, blank=True)
date_created = models.DateTimeField(
'Date Created', auto_now_add=True, null=True)
display = models.BooleanField(default=True)
image = models.ImageField('Panel Image', null=True, blank=True)
def get_absolute_url(self):
return reverse("model_detail", kwargs={"pk": self.pk})
def __str__(self):
return f'{self.name}'
def save(self, *args, **kwargs):
if not self.slug or self.slug != slugify(self.name):
self.slug = slugify(self.name)
return super().save(*args, **kwargs)
views.py
def services(request):
context = {'panels': PanelType.objects.all()}
render(request, 'app/services.html', context)
html
<div class="service-container">
{% for panel in panels %}
<div class="card">
<div class="serviceBx" data-text="{{panel.name}}">
<img src="{{panel.image.url}}" alt="">
</div>
<div class="service-content">
<div>
<h3>{{panel.name}}</h3>
<p>{{panel.description}}</p>
Get Quote
</div>
</div>
</div>
{% endfor %}
</div>
You need to return the result of the render(…) function:
def services(request):
context = {'panels': PanelType.objects.all()}
# ↓ return the HttpResponse
return render(request, 'app/services.html', context)
Working on my first Django project! I have an UpdateView and I want to limit the dropdown results of program_code so it only shows items that the user owns. I think I have to pass kwargs to the view to limit the queryset but not sure where to begin or how to go about doing that. Any advice would be greatly appreciated.
View:
class ContactsUpdateView(LoginRequiredMixin, UserPassesTestMixin, SuccessMessageMixin, UpdateView):
model = Contact
fields = ['first_name1', 'last_name1','address1','address2','city','province','postal_code','country','active_status','program_code']
template_name = 'contacts/contacts_form.html'
success_message = "Contact was updated successfully"
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def test_func(self):
contact = self.get_object()
if self.request.user == contact.author:
return True
return False
model:
class Contact(models.Model):
first_name1 = models.CharField(max_length=100, verbose_name='First Name', null=True)
last_name1 = models.CharField(max_length=100, verbose_name='Last Name', null=True)
address1 = models.CharField(max_length=100, verbose_name='Address 1', null=True)
address2 = models.CharField(max_length=100, verbose_name='Address 2', null=True, blank=True)
city = models.CharField(max_length=100, verbose_name='City', null=True)
province = models.CharField(max_length=2, choices=PROVINCE_CHOICES, default='Ontario', verbose_name='Province')
postal_code = models.CharField(max_length=7, verbose_name='Postal Code', null=True)
country = models.CharField(max_length=100, verbose_name='Country', null=True, default='Canada')
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
active_status = models.BooleanField(default=True)
program_code = models.ForeignKey(Program, on_delete=models.CASCADE)
def __str__(self):
return self.first_name1 + ' ' + self.last_name1
def get_absolute_url(self):
return reverse('contacts-home')
template form:
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-2 mt-2">Update Contact</legend>
<p>Created by: {{ object.author }}, Last Updated: {{ object.date_posted }}</p>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-info" type="submit">Update</button>
<div class="mt-4"><a class="btn btn-outline-danger btn-sm" href="{% url 'contacts-delete' object.id %}" role="button">Delete Contact</a></div>
</div>
</form>
You can try like this:
# form
class ContactForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None) # This will be sent from View
super(ContactForm, self).__init__(*args, **kwargs)
self.fields['program_code'].queryset = Program.objects.filter(owner=user)
class Meta:
model = Contact
fields = ['first_name1', 'last_name1','address1','address2','city','province','postal_code','country','active_status','program_code']
#view
class ContactsUpdateView(LoginRequiredMixin, UserPassesTestMixin, SuccessMessageMixin, UpdateView):
model = Contact
from_class = ContactForm
template_name = 'contacts/contacts_form.html'
success_message = "Contact was updated successfully"
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def get_form_kwargs(self):
# Sending user information to Form
kwargs = super(ContactsUpdateView, self).get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
Here in the View, we are overriding the get_form_kwargs method to pass current user information to the Form. And inside the form, we are overriding the __init__ method to catch the user data sent from View, and use it to override default queryset value of the field program_code.
I'm trying to use django formset for the first time in order to combine both forms on the same page.
My form is well displayed but I don't overvome to save data in my database. When I click on submit button, nothing happens.
This is my model.py file :
class Publication(models.Model):
title = models.CharField(max_length=512, verbose_name=_('title'), null=False)
category = models.ForeignKey(Category, verbose_name=_('category'), null=False)
creation_date = models.DateTimeField(auto_now_add=True, verbose_name=_('creation date'), null=False)
modification_date = models.DateTimeField(auto_now=True, verbose_name=_('modification date'), null=False)
class Meta:
verbose_name = _('publication')
verbose_name_plural = _('publication')
def __str__(self):
return f"{self.title}"
class Document(models.Model):
FORMAT_CHOICES = (
('pdf', 'pdf'),
('epub', 'epub'),
)
format = models.CharField(max_length=10, verbose_name=_('format'), choices=FORMAT_CHOICES, null=False)
title = models.CharField(max_length=512, verbose_name=_('title'), null=False)
publication = models.ForeignKey(Publication, verbose_name=_('publication'), null=False)
upload = models.FileField(upload_to='media/', default="")
creation_date = models.DateTimeField(auto_now_add=True, verbose_name=_('creation date'), null=False)
modification_date = models.DateTimeField(auto_now=True, verbose_name=_('modification date'), null=False)
class Meta:
verbose_name = _('document')
verbose_name_plural = _('document')
def __str__(self):
return f"{self.age_id} : {self.title}"
My form file is very simple too with defined Formset :
class PublicationForm(forms.ModelForm):
class Meta:
model = Publication
fields = ('title', 'category')
class DocumentForm(forms.ModelForm):
class Meta:
model = Document
fields = ['publication', 'format', 'title', 'upload']
DocumentFormSet = inlineformset_factory(Publication, Document, form=DocumentForm, extra=1)
My view is a bit more complicated :
class PublicationCreateUpdateView(AgePermissionRequiredMixin, UpdateView):
""" Display a form to create or update a publication
Only for age admin.
**Context**
``subtitle``
Title of the page
**Template:**
:template:`app/category_form.html`
"""
model = Publication
form_class = PublicationForm
success_url = reverse_lazy('app:app-publication-list')
template_name = 'app/publication_form.html'
permission_required = 'publication.change_webapplication'
def get_object(self, queryset=None):
try:
return super(PublicationCreateUpdateView, self).get_object(queryset)
except AttributeError:
return None
def get_title(self):
if self.object:
return _('Edit publication: ') + str(self.object)
return _('Add new publication')
def get_context_data(self, **kwargs):
context = super(PublicationCreateUpdateView, self).get_context_data(**kwargs)
if self.request.POST :
context['documents'] = DocumentFormSet(self.request.POST)
else :
context['documents'] = DocumentFormSet()
context.update({
'subtitle': self.get_title(),
})
return context
def form_valid(self, form):
context=self.get_context_data()
documents = context['documents']
with transaction.atomic():
self.object = form.save()
if documents.is_valid():
documents.instance = self.object
documents.save()
return super(DocumentCreateUpdateView, self).form_valid(form)
And finally my template looks like this :
{% extends "publication/base_backend.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block main %}
<form method="post" novalidate>
{% csrf_token %}
{% crispy form %}
{{ documents.management_form }}
{{ documents.non_form_errors }}
{% crispy documents %}
<br>
<input type="submit" class="btn btn-default" value="{% trans 'Save' %}" />
{% trans 'Cancel' %}
</form>
{% endblock main %}
I don't understand where I could make a mistake, furthermore I'm pretty new with Django Class Based View.
I'm trying to save multiple Images and his parent's data together on the same template.
I have one parent's model(to save normal data) and child's model(to save images). In this case, saving parent's data is working very well. but images are not work.
There isn't any error message.
//model
class QuotationPanchok(models.Model):
whose = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=50, help_text='', default='')
many = models.IntegerField(default='1', help_text='')
design = models.CharField(max_length=3, choices=(('yes', 'yes'), ('no', 'no'),))
sian = models.CharField(max_length=3, choices=(('yes','yes'), ('no', 'no'),))
havefile = models.CharField(max_length=3, choices=(('yes','yes'), ('no', 'no'),))
deadline = models.DateField(blank=True)
addressto = models.CharField(max_length=50, default='', help_text='')
fulltext = models.TextField(max_length=150, blank=True)
status = models.CharField(max_length=7, choices=(('not','not'), ('finish', 'finish'),), default='not')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
class ImagesForQuotation(models.Model):
whose = models.ForeignKey(QuotationPanchok, on_delete=models.CASCADE)
image = models.ImageField(upload_to='images/', blank=True, null=True)
def __str__(self):
return self.whose.title + " Image"
// views
def quotation_create(request):
ImageFormset = modelformset_factory(ImagesForQuotation, fields=('image',), extra=4)
if request.method == 'POST':
form = QuotationCreateForm(request.POST)
formset = ImageFormset(request.POST or None, request.FILES or None)
if form.is_valid() and formset.is_valid():
post = form.save(commit=False)
post.whose = request.user
post.save()
for f in formset:
try:
photo = ImagesForQuotation(whose=post, image=f.cleaned_date['image'])
photo.save()
except Exception as e:
break
return redirect('index')
else:
form = QuotationCreateForm()
formset = ImageFormset(queryset=ImagesForQuotation.objects.none())
context = {
'form': form,
'formset': formset,
}
return render(request, 'quotationapp/quotation_create.html', context)
//forms
class QuotationCreateForm(forms.ModelForm):
class Meta:
model = QuotationPanchok
fields = (
'title',
'many',
'design',
'sian',
'havefile',
'deadline',
'addressto',
'fulltext',
)
def __init__(self, *args, **kwargs):
super(QuotationCreateForm, self).__init__(*args, **kwargs)
for field_name, field in self.fields.items():
field.widget.attrs['class'] = 'form-control'
//template(quotation_create.html)
{% block content %}
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
{{ formset.as_table }}
<input type="submit" class="btn btn-primary" value="">
</form>
{% endblock %}
How can I solve this problem?
Thank you..