I'm trying to make a way to log notes associated with records. When the form is submitted, it's trying to redirect to the same url, but without the record id, which should be required to view the page. I defined it in urls with the record id, so it should be tracker/19/newnote
I want it to route to tracker/19/detail, and I'm not sure why it's routing to tracker/newnote, which doesn't exist in my urls file. Maybe I need to create it?
anyway, here are my files if anyone wants to take a crack at this with me.
models.py
class Record(models.Model):
serial = models.CharField('Serial Number', max_length=9)
product = models.CharField('Product', max_length=6)
ticket = models.CharField('Log/RID', max_length=9)
eng_date = models.DateField('Date Engaged')
customer = models.CharField('Customer', max_length=80)
details = models.TextField('Problem Details', max_length=800)
owner = models.CharField('Owner', max_length=40)
class Note(models.Model):
record = models.ForeignKey(Record, on_delete=models.CASCADE)
note_text = models.TextField('Notes', max_length=2000)
note_date = models.DateField('Date Entered')
views.py
def newnote(request, record_id):
if request.method == 'POST':
form = NoteForm(request.POST)
if form.is_valid():
r = Record.objects.get(pk=record_id)
r.note_set.create(note_text=form.note_text, note_date=form.note_date)
r.save()
return HttpResponseRedirect('/tracker/%s/detail/' % record_id)
else:
form = NoteForm()
return render(request, 'tracker/noteform.html', {'form': form})
forms.py
class NoteForm(ModelForm):
class Meta:
model = Note
fields = ['note_text',
'note_date'
]
widgets = {
'note_date': DateInput(),}
urls.py
urlpatterns = [
path('', views.index, name='index'),
path('create/', views.create, name='create'),
path('<int:record_id>/detail/', views.detail, name='detail'),
path('result/', views.result, name='result'),
path('query/', views.query, name='query'),
path('all/', views.show_all, name='all'),
path('<int:record_id>/newnote/', views.newnote, name='newnote'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
nameform.html template
<div id=form>
<h3>New Note??</h3>
<hr>
<form action="/tracker/newnote/" method="post">
<div id="fields">
{% csrf_token %}
<p>Note:<br>{{ form.note_text }}</p>
<p>Note Date:<br>{{ form.note_date }}</p>
<input type="submit" value="Submit" />
</div>
</form>
</div>
Related
I am working on my project I faced a problem with "COMMENT":
I add a comment as a section when the user clicks "view" button to see the post from the home page.
Django error :
NoReverseMatch at /Post/8
Reverse for 'comments' with arguments '('',)' not found. 1 pattern(s) tried: ['Post/(?P[0-9]+)$']
views.py file
def viewList(request, id):
item = Post.objects.get(id=id)
context = {
'item': item,
'comment_form': comment(),
'comments': item.get_comments.all(),
}
return render(request, 'auctions/item.html', context)
#login_required
def comments(request, id):
listing = Post.objects.get(id=id)
form = comment(request.PSOT)
newComment = form.save(commit=False)
newComment.user = request.user
newComment.listing = listing
newComment.save()
return HttpResponseRedirect(reverse("listing", {'id': id}))
models.py file
class Post(models.Model):
# data fields
title = models.CharField(max_length=64)
textarea = models.TextField()
# bid
price = models.FloatField(default=0)
currentBid = models.FloatField(blank=True, null=True)
imageurl = models.CharField(max_length=255, null=True, blank=True)
category = models.ForeignKey(
Category, on_delete=models.CASCADE, default="No Category Yet!", null=True, blank=True)
creator = models.ForeignKey(User, on_delete=models.PROTECT)
watchers = models.ManyToManyField(
User, blank=True, related_name='watched_list')
date = models.DateTimeField(auto_now_add=True)
# for activated the Category
activate = models.BooleanField(default=True)
def __str__(self):
return f"{self.title} | {self.textarea} | {self.date.strftime('%B %d %Y')}"
class Comment(models.Model):
body = models.CharField(max_length=100)
createdDate = models.DateTimeField(default=timezone.now)
# link to the post model
auction = models.ForeignKey(
Post, on_delete=models.CASCADE, related_name="get_comments")
user = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.BooleanField(default=True)
def __str__(self):
return self.createdDate.strftime('%B %d %Y')
HTML file
<!-- Comments -->
<div class="comments">
<p>Add a comment:</p>
<div class="row">
<div class="col-6">
<form action="{% url 'comments' listing.id %}" method="post">
{% csrf_token %}
<div class="input-group">
{{ comment_form }}
</div>
<input type="submit" value="save" class="btn btn-outline-dark btn-sm m-1"/>
</form>
</div>
{% for comment in comments %}
<div class="col-4">
Comments:
<h4>Name: {{comment.user}}</h4>
<h4>Content: {{comment.body}}</h4>
<h4>Date: {{comment.createdDate}}</h4>
</div>
{% endfor %}
</div>
</div>
url.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("register", views.register, name="register"),
path("category/", views.category, name="category"),
path("Post", views.createList, name="createList"),
#comment url
path("Post/<str:id>", views.viewList, name="viewList"),
path("Post/<int:id>", views.comments, name="comments"),
]
You passed the Post object as item to the template, hence you should resolve the URL with:
<!-- use item not listing ↓ -->
<form action="{% url 'comments' item.id %}" method="post">
…
</form>
Your view to create comments also has some mistakes: you should use request.POST, not request.PSOT:
from django.shortcuts import redirect
#login_required
def comments(request, id):
if request.method == 'POST'
form = comment(request.POST, request.FILES)
if form.is_valid():
form.instance.user = request.user
form.instance.auction_id = id
form.save()
return redirect('viewList', id=id)
Furthermore your comment form should inherit from ModelForm and not Form:
class comment(forms.ModelForm):
class Meta:
model = Comment
fields = ('content',)
widgets = {
'content': forms.Textarea(attrs={"class": "form-control"})
}
finally your urls.py has two (fully) overlapping patterns, you should use a different URL to add the given comment:
urlpatterns = [
# …
#comment url
path('Post/<int:id>', views.viewList, name='viewList'),
path('Post/<int:id>/add', views.comments, name='comments'),
]
Note: Usually a Form or a ModelForm ends with a …Form suffix,
to avoid collisions with the name of the model, and to make it clear that we are
working with a form. Therefore it might be better to use CommentForm instead of
comment.
I cannot Save comments in django
my post model is
#model.py
class Post(models.Model):
thumbnail = models.ImageField()
slug = models.SlugField(null=True)
title = models.CharField(max_length=200)
description = models.TextField()
content = HTMLField(null=True)
categories = models.ManyToManyField(Category)
featured = models.BooleanField()
timeStamp = models.DateTimeField(auto_now_add=True)
commentCount = models.IntegerField(default=0)
viewCount = models.IntegerField(default=0)
def __str__(self):
return self.title
def absoluteUrl(self):
return reverse('postContent', kwargs={
'slug' : self.slug
})
#property
def getComments(self):
return self.comments.all()
my comment model is
#model.py
class Comment(models.Model):
name = models.CharField(max_length=25)
timeStamp = models.DateTimeField(auto_now_add=True)
comment = models.TextField()
post = models.ForeignKey(Post, related_name='comments', on_delete=models.CASCADE)
def __str__(self):
return self.name
my forms.py is
from .models import Post, Comment
class CommentForm(forms.ModelForm):
name = forms.CharField(widget=forms.TextInput(attrs={
'class': 'form-control',
'id' : 'name',
'placeholder': 'Name'
}))
comment = forms.CharField(widget=forms.Textarea(attrs={
'class' : 'form-control w-100',
'id' : 'comment',
'cols' : '30',
'rows' : 9,
'placeholder' : 'Write Comment'
}))
class Meta:
model = Comment
fields = ('name', 'comment')
my view.py is
from .forms import CommentForm
def post(request, slug):
categoryCount = getCategoryCount()
featured = Post.objects.filter(featured=True)
post = get_object_or_404(Post, slug=slug)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
form.instance.post = post
form.save()
else:
form = CommentForm()
context = {
'post' : post,
'featured': featured,
'categoryCount': categoryCount,
'form' : form
}
return render(request, 'post.html', context)
my post.html is
<div class="comment-form">
<h4>Leave a Reply</h4>
<form class="form-contact comment_form" method="POST" action="." id="commentForm">
{% csrf_token %}
<div class="row">
<div class="col-12">
<div class="form-group">
{{ form }}
</div>
</div>
</div>
<div class="form-group">
<button type="submit" class="button button-contactForm btn_1 boxed-btn">Send Message</button>
</div>
</form>
</div>
my urls.py
from Posts.views import posts, post, search
urlpatterns = [
path('admin/', admin.site.urls),
path('posts/', posts, name='postLists'),
path('posts/<slug>', post, name='postContent'),
path('search/', search, name='search'),
path('tinymce', include('tinymce.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I can save comments in admin section but the main problem is when I click the submit button in html the comment is not saving. I am new to django and I cannont figure out the problem.
Is I miss something else?
You can do something like this
temp = form.save(commit=False)
temp.post = post
temp.save()
Update
as per #Abdul Aziz Barkat mentioned you have to change your URL in urls.py add a trailing slash after posts/<slug> and add one more URL to handle POST request
for eg.
from Posts.views import posts, post, search
urlpatterns = [
path('posts/<slug>/', post, name='postContent'),
path('post_comment/<slug>/', post, name='postComment'),
]
and than inside your form action add this
<form method="POST" action="{% url 'postComment' post.slug %}">
and in your view.py
def post(request, slug):
if i upload the image through my admin dashboard, the image will be successfully uploaded, it will appear in media folder in my project directory i specified in settings.py. but if i upload an image through form.py as a user, every other field is saved except for the image field. I've tried most of the solutions on stackoverflow, dont know why mine ain't working.
while debugging i made mainimage a required field, so it threw this error: ValueError: The view products.views.products didn't return an HttpResponse object. It returned None instead.
form.py
from django import forms
from django.utils.translation import gettext_lazy as _
from .models import Product
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = ['name', 'mainimage', 'category', 'preview_text',
'detail_text', 'price','Quantity']
labels = {
'name': _('Product name'),
}
help_texts = {
'name': _('be specific eg Tomatoes, Rice'),
}
error_messages = {
'name': {
'max_length': _("This writer's name is too long."),
},
}
views.py
from django.shortcuts import render, redirect
from .form import ProductForm
from .models import Product
# Create your views here.
def products(request):
if request.method == 'GET':
form = ProductForm()
return render(request, 'products/add_product.html',{'forms':form})
else:
# imagefield is different from other
# fields and it needs to be handles properly
# data fetched from imagefield would be stored
# in request.FILES object.
if request.method == 'POST':
form = ProductForm(request.POST or None, request.FILES or None)
if form.is_valid():
name = form.cleaned_data.get('name')
mainimage = form.cleaned_data.get('mainimage')
category = form.cleaned_data.get('category')
preview_text = form.cleaned_data.get('preview_text')
detail_text = form.cleaned_data.get('detail_text')
price = form.cleaned_data.get('price')
Quantity = form.cleaned_data.get('Quantity')
obj = Product.objects.create(
name = name,
mainimage = mainimage,
category = category,
preview_text = preview_text,
detail_text = detail_text,
price = price,
Quantity = Quantity
)
obj.save()
# form.save()
return redirect('/products/')
else:
form = ProductForm()
return render(request, 'add_product.html', {'form': form})
add_product
{% extends "plugs/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<h4>Add a Product</h4>
<form action="#" method="post" autocomplete="off" enctype="multipart/form-data">
{% csrf_token %}
<!-- {{form_store.store_name|as_crispy_field}}-->
<div class="col-md-3">
{{ forms.name|as_crispy_field }}
</div>
<div class="row">
<div class="col-md-4" >
{{ forms.mainimage|as_crispy_field }}
</div>
<div class="col-md-3">
{{ forms.category|as_crispy_field }}
</div>
</div>
<div class="col-md-5">
{{ forms.preview_text|as_crispy_field }}
{{ forms.detail_text|as_crispy_field }}
<!-- {{ forms.price|as_crispy_field }}-->
{{ forms.Quantity|as_crispy_field }}
</div>
<button type="submit" class="btn btn-success"><i class="fas fa-database"></i>Submit</button>
</form>
{% endblock %}
settings.py
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, '/static/media/')
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
MEDIA_URL = '/media/'
models.py
from django.db import models
# Create your models here.
class Category(models.Model):
title = models.CharField(max_length= 300)
primaryCategory = models.BooleanField(default=False)
def __str__(self):
return self.title
class Product(models.Model):
mainimage = models.ImageField(upload_to='products/', blank=True)
name = models.CharField(max_length=300)
slug = models.SlugField(blank = True)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
preview_text = models.TextField(max_length = 200, verbose_name='Preview Text')
detail_text = models.TextField(max_length= 1000, verbose_name='Detail text')
price = models.FloatField()
Quantity = models.CharField(max_length=150, default='1 quantity')
def __str__(self):
return self.name
project/urls.py
from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('plugs.urls')),
path('products/', include('products.urls')),
path('home/', include('cart.urls')),
# path('products/', include('products.urls')),
]
urlpatterns += staticfiles_urlpatterns()
if settings.DEBUG:
urlpatterns +=static(settings.MEDIA_URL,
document_root = settings.MEDIA_ROOT)
ok better change your view to
if request.method == 'POST':
form = ProductForm(request.POST or None, request.FILES or None)
if form.is_valid():
instance = form.save(commit=False)
instance.name = form.cleaned_data['name']
instance.mainimage = form.cleaned_data['mainimage']
instance.category = form.cleaned_data['category']
instance.preview_text = form.cleaned_data['preview_text']
instance.detail_text = form.cleaned_data.get['detail_text']
instance.price = form.cleaned_data['price']
instance.Quantity = form.cleaned_data['Quantity']
instance.save()
Is your MEDIA_DIR set in your settings.py?
MEDIA_DIR = os.path.join(BASE_DIR, '/static/media/')
ValueError: The view products.views.products didn't return an HttpResponse object. It returned None instead. Means your somewhere in your views you are not returning an Http response. Try indenting last line of your view to at same level as else. It may resolve
I am having a problem to prepopulate a form and also return the image url of the account:
My view:
class DadosProfissionaisViewUpdate(LoginRequiredMixin, FormView):
template_name = 'accounts/udadosprofissionais.html'
form_class = DadosProfissionaisForm
model = DadosProfissionais
def get_initial(self):
obj = DadosProfissionais.objects.get(user = self.request.user)
initial = super(DadosProfissionaisViewUpdate, self).get_initial()
initial = model_to_dict(obj)
return initial
def form_valid(self, form):
obj = DadosProfissionais.objects.get(user = self.request.user)
obj.user = self.request.user
obj.nome_publico = form.cleaned_data['nome_publico']
obj.nome_consult = form.cleaned_data['nome_consult']
obj.cep_atend = form.cleaned_data['cep_atend']
obj.endereco_atend = form.cleaned_data['endereco_atend']
obj.bairro_atend = form.cleaned_data['bairro_atend']
obj.save()
messages.success(self.request, _('Seus dados foram atualizados com sucesso.'))
return redirect('home')
My template:
{% block content %}
<div class="text-center">
<img src="{{ profile_pic.url }}" class="rounded" alt="img">
</div>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{% bootstrap_form form %}
<button class="btn btn-primary">Enviar</button>
</form>
{% endblock %}
My urls - added MEDIA_URL:
urlpatterns = [
path('admin/', admin.site.urls),
........
path('sitemap.xml', sitemap, {'sitemaps': sitemaps}),
path('accounts/', include('accounts.urls')), ]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
My form:
class DadosProfissionaisForm(forms.ModelForm):
nome_publico = forms.CharField(label='Nome Público')
nome_consult = forms.CharField(label='Nome do Consultório')
cep_atend = forms.CharField(label='CEP')
endereco_atend = forms.CharField(label='Rua')
bairro_atend = forms.CharField(label='Bairro')
profile_pic = forms.ImageField(label='Foto')
class Meta:
model = DadosProfissionais
fields = ['nome_publico', 'nome_consult', 'cep_atend', 'endereco_satend',
'bairro_atend', 'profile_pic']
I do not know how the correct way to prepolute the form and also load this image profile url in this template. Can anybody give a hand!? Thanks.
i have some news...
Looking for a way to display the image in a prepopulate form, i read it is not possible because a question of security in django. Well, i will try something else, maybe another template just to change the image without prepopulate it.
Thanks
I created a form in template to insert data in database but form is not working.When i submitted form nothing happened.please review my all code and give me some suggestion.
add.html Template file:
<h2>Add Article</h2>
<form action="" method="post">
{% csrf_token %}
<label>Title</label>
<input type="text" name="title"
placeholder="Enter Title">
<label>Category</label>
<select name="cate">
<option value="">Select Category</option>
{% for cat in get %}
<option value="{{ cat.cate }}">{{ cat.cate }}
</option>
{% endfor %}
</option>
</select>
<label>Discription</label>
<textarea name="desc" rows="15">
</textarea>
<input type="submit" value="submit" class="btn btn-default">
</form>
I created 2 views.in first view i rendered all categories which add in form select menu and 2nd view is for handling form
views.py
from django.shortcuts import render, redirect
from .models import article, category
def get_category(request):
get = category.objects.all()
context = {
'get':get
}
return render(request, 'blog/add.html', context)
def add(request):
if request.method == 'POST':
title = request.POST['title']
cate = request.POST['cat']
desc = request.POST['desc']
art = article(title=title, disc=desc, cat=cate)
art.save()
return redirect('blog/index.html')
else:
return render(request, 'blog/add.html')
Models.py
from django.db import models
class category(models.Model):
cate = models.CharField(max_length=100)
def __str__(self):
return self.cate
class article(models.Model):
title = models.CharField(max_length=250)
disc = models.TextField()
cat = models.ForeignKey(category, verbose_name="Category")
posted = models.DateTimeField(auto_now_add=True, editable=False)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
urls.py
from django.conf.urls import url
from .import views
app_name = 'blog'
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^add/$', views.get_category, name='category'),
url(r'^add/$', views.add, name='add'),
]
In your case every time action go to the get_category, because django find first match urls and use it for action.
You can create one function for your case:
in views.py
def category(request):
if request.method == 'POST':
title = request.POST['title']
# update start
cat = request.POST['cat']
cate = Category.objects.get(pk=cat)
# Update end
desc = request.POST['desc']
art = article(title=title, disc=desc, cat=cate)
art.save()
return redirect('blog/index.html')
get = category.objects.all()
context = {
'get':get
}
return render(request, 'blog/add.html', context)
in urls.py
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^add/$', views.get_category, name='category'),
# !! comment or remove last urls
# url(r'^add/$', views.add, name='add'),
]
I edit but if you look and rebuild your logic with django forms it will be better.
<input type="submit" class="btn btn-primary" value="Add item">
Add a Submit button instead of type = 'button'
reconfig project(makemigration and migrate) if POST method is not working
Change:
return redirect(request, 'blog/index.html')
To:
return redirect('index')
'index' is the name attribute of view function in views.py file. As redirect doesn't take 'request' argument as parametre.