Hi im developping a blog app and i am creating a simple like button for the post idintified by it's pk where the link is located in a form but it ran into an error.
NoReverseMatch at /single_post/8/
Reverse for 'like_post' not found. 'like_post' is not a valid view function or pattern name.
my views.py for the detail view and the like button view
def post_detail(request, pk):
post = Post.objects.get(id=pk)
context = {
'post': post,
}
return render(request, 'news/post_detail.html', context)
def LikeView(request, pk):
post = get_object_or_404(Post, id=request.POST.get('post_id'))
post.likes.add(request.user)
return(HttpResponseRedirect(reverse('single_post', args=[str(pk)] )))
models.py
class Post(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
image = models.ImageField(upload_to='img/', default='img/default.jpg')
author = models.CharField(max_length=100)
date = models.DateTimeField(auto_now_add=True)
credit = models.URLField(blank=True, null=True)
likes = models.ManyToManyField(User, related_name='daily_posts')
def __str__(self):
return self.title
in the detail views the form and the link
<form action="**{% url 'like_post' post.pk %}**" method="POST">
{% csrf_token %}
<button class="btn btn-primary btn-sm" type="submit", name="post_id", value="{{ post.id }}">Like</button>
</form>
and the error i run to everytime i hit like.
NoReverseMatch at /single_post/8/
Reverse for 'like_post' not found. 'like_post' is not a valid view function or pattern name.
i cannot identify what seems to be the issue here anyone can help please?
In LikeView, you reverse 'single_post' but in the form you have 'like_post'. Perhaps change 'single_post' in LikeView to 'like_post'? EDIT FOR NAMESPACE: I believe you need to include the namespace in the form i.e. {% url 'news:like_post' post.pk %}
Related
Completely new to all computer programming and trying to build an app that tracks my smoking habits. The first step was creating a Django model called packs:
class packs (models.Model):
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False, blank=False)
num_packs = models.SmallIntegerField(max_length=10)
cost_packs = models.DecimalField(max_digits=6, decimal_places=2)
Next I created a forms.py page and this is where I started getting lost:
from django.forms import ModelForm
from .models import packs
class packsForm(ModelForm):
class Meta:
model = packs
fields = ['num_packs', 'cost_packs']
Of course that led to my failure in HTML trying to render a page that has all the form data:
{%block content%}
<div class = "form_pack">
<h3>FORM PACK</h3>
<p>
<form method="POST" action="."> {% csrf_token %}
<input text="cost_pack" name=cost_pack>
{{ form }}
<input type="submit" value="save"/>
</form>
</p>
</div>
{% endblock %}
To help my view.py looks like this:
def packs_create(request):
form=packsForm(request.POST or None)
if form.is_valid():
return render(request, 'pack/index.htmnl', {'form': form})
Now when I refresh the page I don't get the form. Just the one input i put in.
Can someone help me sort out which path I got lost in and where I need to connect the dots? I believe my forms.py is not complete, but not sure where to progress...
Thanks,
DrKornballer
Just update your views.py and forms.py you will get your form and can save the data entered.
views.py
def packs_create(request):
if request.method == "POST":
form = packsForm(request.POST)
if form.is_valid():
form.save(commit = True)
else:
form = PacksForm()
return render(request, 'pack/index.html', {'form': form})
forms.py
class packsForm(ModelForm):
class Meta:
model = packs
fields = ('num_packs', 'cost_packs')
I have been trying to learn Django.
I am stuck on this form part. A form has been created that allows the user to create an Album object where they can fill in the Artist, Album Name, Genre and upload an Album Logo. When I fill in the fields and then click submit, it should then redirect me to the details page for that particular Album that just got created. But nothing appears to happen when clicking the submit button and the object does not get created.
Here is the models.py code that contains an Album class with 4 fields; artist, album_name, genre and album_logo.
from django.db import models
from django.urls import reverse
# Create your models here.
class Album(models.Model):
artist = models.CharField(max_length=250)
album_name = models.CharField(max_length=500)
genre = models.CharField(max_length=100)
album_logo = models.ImageField()
def get_absolute_url(self):
return reverse('music:detail', kwargs={'pk':self.pk})
def __str__(self):
return self.album_name + " - " + self.artist
class Song(models.Model):
album = models.ForeignKey(Album, on_delete=models.CASCADE)
file_type = models.CharField(max_length=100)
song_title = models.CharField(max_length=250)
is_favourite = models.BooleanField(default=False)
def __str__(self):
return self.song_title
Here is the album_form.html code which contains the actual form. I have not used crispy_forms as I am not familiar with Bootstrap though I know CSS.
{% extends 'music/base.html' %}
{% block title %}Add a New Album{% endblock %}
{% block body %}
<form class="formContainer" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
{% if field.label != 'Album logo' %}
<label for="field{{ forloop.counter }}">{{ field.label }}</label>
<input type="text" id="field{{ forloop.counter }}" name="" value="">
{% else %}
<label for="field{{ forloop.counter }}">{{ field.label }}</label>
<input type="file" id="field{{ forloop.counter }}" name="" value="" accept="image/*">
{% endif %}
<br>
{% endfor %}
<input type="submit" id="submitBtn" name="" value="Add">
</form>
{% endblock %}
This is views.py code where I have made use of class based views and not function based views.
from django.views import generic
from .models import Album, Song
# Create your views here.
class IndexView(generic.ListView):
template_name = 'music/index.html'
queryset = Album.objects.all()
context_object_name = 'all_albums'
class DetailView(generic.DetailView):
model = Album
template_name = 'music/detail.html'
class AlbumCreate(generic.CreateView):
model = Album
fields = ['artist', 'album_name', 'genre', 'album_logo']
def form_valid(self, form):
return super().form_valid(form)
and finally this is my urls.py code:
from django.urls import path, include
from . import views
app_name='music'
urlpatterns = [
#/music/
path('', views.IndexView.as_view(), name='index'),
#/music/5/
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
#/music/album/add/
path('album/add/', views.AlbumCreate.as_view(), name='album-add')
]
After clicking the submit button in the form, it should take me to the "detail" url for the primary key of the Album that got created. Am I missing something here?
In your views.py you need to override the get_success_url function in your CreateView and pass the id as an argument while redirecting.
class AlbumCreate(generic.CreateView):
model = Album
fields = ['artist', 'album_name', 'genre', 'album_logo']
def form_valid(self, form):
return super().form_valid(form)
def get_success_url(self):
return reverse('music:detail', args=(self.object.id,))
Seems you forgot to put action to your <form> tag
Try this
<form class="formContainer" action='{% url 'music:album-add'%}' method="post" enctype="multipart/form-data">
Edit: Also add success url using get_success_url function in your AlbumCreate view to redirect user to album detail page, like was mentioned in above answer
from django.urls import reverse_lazy
...
class AlbumCreate(generic.CreateView):
...
def get_success_url(self, **kwargs):
return reverse_lazy('music:detail', args = (self.object.id,))
I'm having some trouble with a django blog that I'm working on, and I was wondering if someone could help me out.
https://github.com/kevin-reaves/Blog
localhost:8000/posts/create
Basically, when I go to create a blog post using the creation form everything seems to work aside from uploading the actual image. The admin console seems to think there's an image at the correct location, but nothing gets uploaded there.
Here's the password for the admin console
admin
password123
Edit: Added some relevant code
<form action="{% url 'create' %}" method="POST">{% csrf_token %}
<p>Title:</p>
<input type="text" name="title"/>
<br/>
<p>Image:</p>
<input type="file" name="image"/>
def create(request):
if request.method == 'POST':
if request.POST['title'] and request.POST['body']:
post = Post()
post.title = request.POST['title']
post.pub_date = timezone.datetime.now()
post.image = request.POST['image']
post.body = request.POST['body']
post.author = request.user
post.save()
return redirect('home')
class Post(models.Model):
title = models.CharField(max_length=250)
pub_date = models.DateTimeField()
author = models.ForeignKey(User, db_column="user", default=1)
image = models.FileField(upload_to='media', blank=True)
body = HTMLField()
Quick find... you need two changes this to work.
Add enctype="multipart/form-data" in your html form
use request.FILES['image']
I just created a form for the first time and have some questions regarding the process and where the data is going.
Here are my models, views, forms, urls, and templates files;
The model from models.py:
class Member(models.Model):
member_id = models.SlugField(max_length=10)
name = models.CharField(max_length=200)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
mobile = models.SlugField(max_length=20)
income = models.CharField(max_length=200, choices=INCOME_CHOICES)
education = models.CharField(max_length=200, choices=EDUCATION_CHOICES)
home_district = models.CharField(max_length=200, choices=DISTRICT_CHOICES)
family_spending = models.CharField(max_length=200, choices=FAMILY_SPENDING_CHOICES)
children_spending = models.CharField(max_length=200, choices=CHILDREN_SPENDING_CHOICES)
birth_date = models.DateTimeField('Birthday', blank=True)
comments = models.CharField(max_length=300, blank=True)
def __str__(self):
return self.name
views.py:
def create_a_member_form(request):
if request.method == 'POST':
form = MemberForm(request.POST)
if form is valid():
member_form = form.save()
return HttpResponseRedirect('/complete/')
else:
form = MemberForm()
return render(request, 'member_form.html', {'form': form})
forms.py:
from .models import Member
from django import forms
class MemberForm(forms.ModelForm):
class Meta:
model = Member
fields = '__all__'
urls.py:
urlpatterns = [
url(r'^member_form/$', views.create_a_member_form, name='member_form')
]
The template (member_form.html):
{% load staticfiles %}
<form action="/admin/" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
I want to know:
In the template, what does the /admin/ in <form action="/admin/" method="post"> represent? It's where the page redirects to after I click 'Submit', right?
Does the name='member_form' in urls.py represent the name of the HTML template the URL will match to, in thise case member_form.html?
Where is the data created from the form going? I've tried creating Member objects using the form but the new objects do not show up in my admin site under Members (while existing ones do). How do I make sure the objects created from this form do show up in my Admin site under Members?
Thank you.
Yes.
No, it's the name you use in a {% url %} tag if you want to generate a link pointing at that URL. The template is determined by the view itself (in render(request, 'member_form.html',...)).
It's not going anywhere, because your view is posting to /admin/ instead of /member_form/; /admin/ is the index of the admin site which has no code to actually accept your form data.
Note that 1 is basic HTML, and 2 and 3 are basic Django concepts which are covered in the tutorial; you should go and read that.
Hey so I set up a input form for users to share projects they are working on on a website I have been developing in Django 1.5, I created model, view and Form Model, to allow users who are logged in to add links to projects they are working on.
The Model works and when I enter a text through the admin panel it creates a new object, the views all seem to work, the form loads, and seems to take input however, the Project Name field keeps throwing me a invalid input error when I attempt to fill out the form, not sure why because I am inputing a string, and the field is designated as a CharField in both the Model, and Form Model.
Model:
class Project(models.Model):
creator = models.ForeignKey(User)
project_name = models.CharField(max_length=128)
website = models.URLField(blank=True)
github = models.URLField(blank=True)
description = models.CharField(max_length=255, unique=True)
likes = models.IntegerField(default=0)
def __unicode__(self):
return self.nam
View for adding a project:
#login_required
def add_project(request):
context = RequestContext(request)
if request.method == 'POST':
form = ProjectForm(request.POST)
if form.is_valid():
form.save(commit=False)
project.creator = request.user
project.save()
return index(request)
else:
print form.errors
else:
form = ProjectForm()
return render_to_response('rango/add_project.html', {'form' : form}, context)
The Form Model:
class ProjectForm(forms.ModelForm):
project_name = forms.CharField(max_length=128, help_text="What is the name of your project?")
website = forms.CharField(max_length=200, help_text="Enter the project website:")
github = forms.CharField(max_length=200, help_text="Enter the project github:")
description = forms.CharField(widget=forms.Textarea, help_text="Description:")
likes = forms.IntegerField(widget=forms.HiddenInput(), initial=0)
class Meta:
model = Project
exclude = ('creator')
def clean(self):
cleaned_data = self.cleaned_data
website = cleaned_data.get('website')
#If Url is not empty and dont start with 'http://' prepend 'http://'
if website and not website.startswith('http://'):
website = 'http://' + website
cleaned_data['website'] = website
return cleaned_data
def clean(self):
cleaned_data = self.cleaned_data
github = cleaned_data.get('github')
#If Url is not empty and dont start with 'http://' prepend 'http://'
if github and not github.startswith('http://'):
github = 'http://' + github
cleaned_data['github'] = github
return cleaned_data
and lastly the html template:
{% extends 'rango/base.html' %}
{% block title %} Add Project {% endblock %}
{% block body_block %}
<H1>Add a new Project</H1>
<form id="project_form" method="post" action="/rango/add_project/">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{hidden}}
{% endfor %}
{% for field in form.visible_fields %}
{{field.errors}}
{{field.help_text}}
{{field}}
{% endfor %}
<input type="submit" name="submit" value="Create Project" />
</form>
{% endblock %}
The Page loads fine but when I attempt to submit i get this for project name:
Enter a valid value.
the value I entered was test for project name.
In the view function, I do not understand from where project comes from.
I would expect instead:
project = form.save(commit=False)
project.creator = request.user
project.save()