Trying to create a form for my polls app.But I am not able to include choices as well for it.I can only add polls right now through admin.
(Its the official django polls app tutorial and i am trying to extend it further by adding a form)
Models.py
class Question(models.Model):
question_text = models.CharField(max_length=200)
publish_date = models.DateTimeField('date published',null=True,blank=True)
def __str__(self):
return self.question_text
def get_absolute_url(self):
return reverse('polls:index')
class Choice(models.Model):
question_text = models.ForeignKey(Question,on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
forms.py
class QuestionForm(forms.ModelForm):
question_text = forms.CharField(required=True)
publish_date = forms.CharField(required=False)
choice_text = forms.CharField(required=True)
class Meta():
model = Question
fields = ('question_text','choice_text')
View To create Poll
class CreatePoll(CreateView):
redirect_field_name = 'polls/index.html'
template_name = 'polls/poll_form.html'
form_class = QuestionForm
model = Question
This is My Form View But the choice entered doesnt get saved.Saw in the admin view too
polls_form.html
{% extends 'polls/base.html' %}
{% block content %}
<h1>New Post</h1>
<form class="post-form" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
<button type="submit" class="save btn btn-primary">Save</button>
</form>
<script>var editor = new MediumEditor('.editable');</script>
{% endblock %}
Related
I am looking for guidance on where I am going wrong. My model form is rendering correctly however the author has no option to select or input. I suspect this is is because the author is a foreign key. How do I get around this so the form will display a list of users or allow to manually input a name. Any help would be greatly appreciated :)
models.py
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE,
related_name="workout_posts")
updated_on = models.DateTimeField(auto_now=True)
featured_image = CloudinaryField('image', default='placeholder')
content = models.TextField(default='SOME STRING')
excerpt = models.TextField(blank=True)
created_on = models.DateTimeField(auto_now_add=True)
class Meta:
# ordered created on field starting with newest first
ordering = ['-created_on']
def __str__(self):
return self.title
forms.py
class MakeWorkOutForm(forms.ModelForm):
class Meta:
model = Post
fields = '__all__'
views.py
def createWorkOut(request):
form = MakeWorkOutForm
context = {'form': form}
return render(request, "add-workout.html", context)
html
{% extends "base.html" %} {% block content %} {% load static %}
<h1>Create A Workout</h1>
<form action="" method="POST">
{% csrf_token %}
{{form}}
<input type="submit" name="submit">
</form>
{% endblock content %}
I am building a Django project where I have an index page that lists all posts. The user can click on the name of a post and this will take them to a detail page with the complete post information (date, content, category). This detail page also has a link that will take the user to a form where they can leave a comment. Once the user clicks submit they are supposed to navigate back to the post detail page and the comment is supposed to be there. The issue I am having right now is that the comment is being automatically assigned to the first post in the index list rather than the post the user had visited (I think this may have something to do with the current default setting in my models, but how else can I get the post id?). How can I make it so that the comment is assigned to its correct post? I have tried everything with the models and views but nothing seems to work. Thank you for your help, I think the solution to this might be simple but I can't find it anywhere.
Here is my relevant models:
class UserPost(models.Model):
title = models.CharField(max_length=255)
category = models.ForeignKey('Category', on_delete=models.SET_NULL, null=True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(User, default=1,
on_delete = models.CASCADE
)
#id = models.AutoField(primary_key=True)
def __str__(self):
"""String for representing the UserPost object."""
return self.title
def get_absolute_url(self):
"""Returns the url to access a detail record for this user post."""
return reverse('userpost-detail', args=[str(self.id)])
class Comment(models.Model):
author = models.ForeignKey(User, default=1,
on_delete = models.CASCADE
)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
def comment_default():
return {UserPost.id}
post = models.ForeignKey(UserPost, default= comment_default, on_delete=models.CASCADE, related_name="comments")
def __str__(self):
"""String for representing the comment object."""
return '%s - %s - %s' % (self.post.title, self.author, self.created_on)
def get_absolute_url(self):
return reverse('userpost-detail', args=[str(self.post.id)])
And my views:
class UserPostDetailView(generic.DetailView):
model = UserPost
#post = UserPost.objects.get(id=id)
#comments = Comment.objects.filter(Comment.post)
def get_context_data(self, **kwargs):
context = super(UserPostDetailView, self).get_context_data(**kwargs)
context['Comment'] = UserPost.comments
return context
class PostCreate(CreateView):
model = UserPost
fields = ['title', 'category', 'content']
class CommentCreate(CreateView):
model = Comment
fields = ['post','content']
And my html:
{% extends "base.html" %}
{% block page_content %}
<h1>Title: {{ userpost.title }}</h1>
<p><strong>Author:</strong> {{ userpost.author }}</p>
<p><strong>Content:</strong> {{ userpost.content }}</p>
<p><strong>Category:</strong> {{ userpost.category }}</p>
<a class="btn btn-primary" href="{% url 'comment-create' %}" role="button">Leave a Comment</a>
<h3>Comments:</h3>
{% for comment in userpost.comments.all %}
<p>
On {{comment.created_on.date }}
<b>{{ comment.author }}</b> wrote:
</p>
<p>{{ comment.content }}</p>
<hr>
{% endfor %}
{% endblock %}
You need to pass Post ID in your url for this.
path("comment/<int:post_id>/", CommentCreateView, name="comment-create")
Now in template
<a class="btn btn-primary" href="{% url 'comment-create' userpost.id %}" role="button">Leave a Comment</a>
Views
class CommentCreateView(CreateView):
model = Comment
fields = ['content'] # remove field post here
def form_valid(self, form):
form.instance.post_id = self.kwargs.get("post_id")
return super().form_valid(form)
I am trying to make a contact form but it's html template does not see {{ form }} template. What am I doing wrong? Where is an error.
My code is attached above.
models.py
class Contact(models.Model):
listing = models.CharField(max_length=200)
listing_id = models.IntegerField()
name = models.CharField(max_length=200)
email = models.EmailField()
phone = models.CharField(max_length=100)
message = models.TextField(blank=True)
file = models.FileField(upload_to='files/%Y/%m/%d/', blank=True)
contact_date = models.DateTimeField(default=datetime.now, blank=True)
user_id = models.IntegerField(blank=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('listings', kwargs={'pk': self.pk})
In views.py file
class ContactCreate(CreateView):
model = Contact
form_class = ContactForm
template_name = 'listing.html'
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('listings/<int:pk>/', views.ContactCreate.as_view(), name='contact-create')
]
html
<form action="{% url 'contact-create' pk=listing.pk %}" method="post">
{{ form }}
{% csrf_token %}
<input type="submit" value="Send" class="btn btn-block btn-secondary">
</form>
forms.py
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
fields = ['name','email','phone','file']
Could you help me out, please
If you provide a form_class with ContactForm, Django is expecting a form to be provided so you have two options:
Create a form.py and add the following:
from django import forms
class ContactForm(forms.Form):
name = forms.CharField()
message = forms.CharField(widget=forms.Textarea)
Don't forget to add that to your view:
from myapp.forms import ContactForm
If you want your custom form to be display you have to specify the form_class in your create view:
form_class = ContactForm
If you are using a custom template to display your form add the following to your create view:
template_name = 'listing.html' # or the path to your template
Im trying to create an update view for my django blog project and I haven't been able to figure it out. I have a model that creates a url based on the date it was posted and the title which also goes through a random slug generator it was given and Im having trouble passing that url to the update view I keep getting the error "AttributeError at /posts2020/7/24/hello-93ej/update/
Generic detail view PostUpdateView must be called with either an object pk or a slug in the URLconf"
here is my code
models.py
class Post(models.Model):
STATUS_CHOICES = (
('cleared','Cleared'),('UnderReview','Being Reviewed'),('banned','Banned'),)
title = models.CharField(max_length = 300)
slug = models.SlugField(max_length = 300, unique_for_date='publish')
author = models.ForeignKey(User, on_delete=models.SET_NULL, related_name='forum_posts',null=True)
body = models.TextField()
publish = models.DateTimeField(default=timezone.now)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=12,choices=STATUS_CHOICES,default='cleared')
objects = models.Manager()
cleared = PublishedManager()
class Meta:
ordering =('-publish',)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('posts:post_detail', args=[self.publish.year, self.publish.month, self.publish.day, self.slug])
urls.py
from . import views
from django.urls import path, include
from django.contrib.auth import views as auth_views
from .views import PostListView, PostCreateView,PostUpdateView
app_name = 'posts'
urlpatterns = [
path('', views.PostListView.as_view(), name='post_list'),
path('<int:year>/<int:month>/<int:day>/<slug:post>/',views.post_detail,name='post_detail'),
path('post/new/',PostCreateView.as_view(), name='post-create'),
path('<int:year>/<int:month>/<int:day>/<slug:post>/update/',PostUpdateView.as_view(), name='post-update'),
views.py
class PostUpdateView(LoginRequiredMixin, UpdateView):
model = Post
fields = ['title','body']
def get_success_url(self):
return reverse('posts:post-update', args=[self.publish.year, self.publish.month, self.publish.day, self.slug])
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
post-update.html
{% extends "Main/Base.html" %}
{% block title %} Update a post {% endblock %}
{% block content %}
{% if request.user.is_authenticated %}
<h1> Update a post <h1>
<p>You can Update your post using the following form:</p>
<form method="post">
{{ form.as_p }}
{% csrf_token %}
<p><input type="submit" value="Update"></p>
</form>
{% endif %}
{% endblock %}
You can filter the objects by overriding the get_object:
from django.shortcuts import get_object_or_404
class PostUpdateView(LoginRequiredMixin, UpdateView):
model = Post
fields = ['title','body']
def get_object(self, *args, **kwargs):
return get_obect_or_404(
Post,
publish__year=self.kwargs['year'],
publish__month=self.kwargs['month'],
publish__day=self.kwargs['day'],
slug=self.kwargs['post'],
author=self.request.user
)
def get_success_url(self):
return reverse(
'posts:post-update',
args=[
self.object.publish.year,
self.object.publish.month,
self.object.publish.day,
self.object.slug
]
)
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
The author=self.request.user filter part, will ensure that if the logged in user is not the author, it will raise a HTTP 404 response instead of letting that user edit the post.
I have the following model in my Django project:
from django.contrib.auth.models import User
class Project(models.Model):
project_title = models.CharField(max_length=200)
project_description = models.CharField(max_length=200, default="")
created_date = models.DateTimeField('date created')
owner = models.ForeignKey(User)
def __str__(self):
return self.project_title
This view uses the Project model as follows:
class ProjectView(generic.edit.UpdateView):
model = Project
fields = ['project_title','project_description']
template_name = 'steps/project.html'
success_url = reverse_lazy('steps:index')
My question is how can I bring the User's fields into my ProjectView so I can then use them in templates? In particular, I would like to display the logged-in user's name and email.
user information placed on request, not on views. So you can write in template {{user.username}}, or {{user.email}}. and you'll get it. Of course if user.is_authenticated
in your template write:
{% if request.user.is_authenticated %}
{{ request.user.username }}
{{ request.user.email }}
{% endif %}