I can not display Django form - python

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

Related

Select2 widget showing on Django Admin site but not on the form template in Django4

I have two object models, NewsObject and StockObject. The stock object is a foreign key in the news object.
class stockObject(models.Model):
stock_name = CharField(max_length=100, blank=True, null=True)
stock_tag = CharField(max_length=100, blank=True, null=True)
def __str__(self):
return self.stock_name
class newsObject(models.Model):
title = CharField(max_length=100, blank=True, null=True)
body = TextField(blank=True, null=True)
stock = ForeignKey(stockObject, on_delete=models.SET_NULL, blank=True, null=True)
I have used autocomplete_fields property in the ModelAdmin class as I want a searchable dropdown for stocks in news. I have also added search_fields in the stocks ModelAdmin as mentioned in the documentation.
This is what my admin.py looks like:
class stockAdmin(admin.ModelAdmin):
list_display = ['stock_name', 'stock_tag']
search_fields = ['stock_name']
class newsAdmin(admin.ModelAdmin):
list_display = ['title', 'body', 'stock']
search_fields = ['title', 'body', 'stock']
autocomplete_fields = ['stock']
Now, the issue is that I get a searchable dropdown on the Django Admin site for this field, but it is only a dropdown (not searchable) on the actual template screen. I have a basic view which calls the template, like so:
Views.py
def createNews(request):
form = NewsForm()
if request.method == 'POST':
form = NewsForm(request.POST)
if form.is_valid():
form.save()
return redirect('/backoffice/')
context = {'form' : form}
return render(request, 'NewsForm.html', context)
And NewsForm.html is:
{% extends "base.html" %}
{% load static %}
{% block content %}
<form action="" method="POST">
{% csrf_token %}
{{ form }}
<input type="submit" name="Submit">
</form>
{% endblock %}
I've been wondering what might be the cause of this behavior. Tried multiple things but none of them work. What might I be missing here?
Django Admin site image
Django Template Image
I think you have written all your models in camelCase so first changed them to PascalCase.
Second, you have missed models in all your models:
Write them like this add models before every datatype like:
from django.db import models
class Musician(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
instrument = models.CharField(max_length=100)
Not only datatype of fields.

Django admin cant display upload files by form

I have model where I can upload files without problem, and a model forms which upload the file, which get the path perfectly when I call them in a html loop; but this files can't be accessed by django admin interface. In the two cases the uploaded files can by get in the defined media_root.
What am I doing wrong?
models.py
class Documentos(models.Model):
user = models.OneToOneField(User, on_delete="models_CASCADE", null=True, blank=True)
nome = models.CharField(max_length=200, default='Arquivo')
documento = models.FileField(upload_to='')
data = models.DateField(auto_now_add=True)
formatado = models.BooleanField(default=False)
class Meta:
verbose_name = 'Documento'
verbose_name_plural = 'Documentos'
def __str__(self):
return self.nome
forms.py
class DocumentosForm(forms.ModelForm):
class Meta:
model = Documentos
fields = ['user','nome','documento']
views.py
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.core.files.storage import FileSystemStorage
from .forms import *
from .models import *
def alfa(request):
return render(request, 'pdfupload.html')
# Create your views here.
#login_required(login_url='/register')
def upload(request):
context = {}
if request.method == 'POST':
uploaded_file = request.FILES['document']
fs = FileSystemStorage()
name = fs.save(uploaded_file.name, uploaded_file)
context['url'] = fs.url(name)
return render(request, 'pdfupload.html', context)
def documentos_lista(request):
return render(request, 'lista.html')
def upload_documento(request):
return render(request, 'documento_upload.html')
forms.html:
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="document" />
<input type="submit" name="submit" value="Upload" />
</form>
I have my project/urls.py:
...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I am using django 2.1
Even I can't get the uploadedfiles by forms in django admin, no error message is returned.
I am very grateful for your help. Thank you, have a nice day.

Django, comments cannot get the name of the post they are on

I'm having an issue with Python Django. It has to do with foreign keys and models. I have been told before that my questions are often incredibly mediocre, so please bear with me on this. I am trying to configure comments for a social network I'm working on and I've just got comments working, kind of. The issue is that, although I can input a comment and the database will log it and the person who wrote it, it won't log the post it is on. It always returns null. This is really the full extent of what I can say, as I REALLY don't understand what is happening. Here are a number of different code snippets and image that should hopefully be able to elaborate on the issue without requiring my interjection.
1:
The models of the post-app
https://pastebin.com/XXNsCa5g
The important model being:
class Comment(models.Model):
2:
The reply template:
https://pastebin.com/GsLUQqYp
3:
The reply view:
class PostReplyView(CreateView):
model = models.Comment
template_name = 'post_reply.html'
fields = ['comment']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
Finally, a visual representation of what is missing from a comment when it is posted:
enter image description here
Updated using normal view:
models.py
from django.db import models
from user.models import MyUser
from django.urls import reverse
# Create your models here.
class Post(models.Model):
user = models.ForeignKey(MyUser, on_delete=models.CASCADE)
title = models.CharField(max_length=255)
content = models.TextField()
posted_on = models.DateTimeField(auto_now=True, auto_now_add=False)
updated_on = models.DateTimeField(auto_now=False, auto_now_add=True)
slug = models.SlugField(blank=True, null=True)
def __str__(self):
return "%s by %s" % (self.title, self.user.get_full_name())
def get_absolute_url(self):
return reverse('post:detail', kwargs={'slug':self.slug})
class Comment(models.Model):
author = models.ForeignKey(MyUser, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
comment = models.TextField()
posted_on = models.DateTimeField(auto_now_add=True, auto_now=False)
def __str__(self):
return "%s commented on %s" % (self.author, self.post)
forms.py
from django import forms
from .models import Post, Comment
class newPost(forms.ModelForm):
class Meta:
model = Post
fields = ['title','content']
class newComment(forms.ModelForm):
class Meta:
model = Comment
fields = ['comment']
views.py
def detail(request, slug=None):
post = get_object_or_404(Post, slug=slug)
user = request.user
if request.method == 'POST':
comment = newComment(request.POST)
if comment.is_valid():
new_Comment = comment.save(commit=False)
new_Comment.author = user
new_Comment.post = post
new_Comment.save()
# successfully commented, now do whatever you want
return HttpResponse('commented')
else:
comment = newComment()
context = {
'post' : post,
'comment' : comment
}
return render(request, 'post/detail.html', context)
detail.html
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
<hr>
<form action="" method="post">
{% csrf_token %}
{{ comment.as_p }}
<input type="submit">
</form>
** you are getting empty field on "post" because you are not linking it with any post, but in the above example i have shown you how i have done it and how you can also do the same for your project **

Using Django's 'get_absolute_url' (return the user to the same page after form submission)

I am learning Django and have one question.
I have done a feedback form and I need to redirect the user to the same page after the feedback form confirmation. Below is the code:
models.py
class Feedback(models.Model):
title = models.CharField(max_length=255)
text = models.TextField(max_length=5000)
user_name = models.CharField(max_length=255)
user_lastname = models.CharField(max_length=255)
email = models.EmailField(max_length=255)
send_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
def get_absolute_url(self):
return
urls.py
url(r'^feedback$',views.FeedbackSendForm.as_view(), name='feedback'),
views.py
class FeedbackSendForm(CreateView):
model = Feedback
fields = [
'title',
'text',
'user_name',
'user_lastname',
'email',
]
template_name = 'feedback.html'
feedback.html
<form method="post">
{% csrf_token %}
{% for field in form %}
<span class="text-danger">{{ field.errors }}</span>
<div>
<label class="control-label">{{ field.label }}</label>
{{ field }}
</div>
{% endfor %}
<button type="submit">Submit</button>
</form>
How can I fix this?
If you want to override the get_absolute_url for your model, the following code can help you:
from django.urls import reverse
class Feedback(models.Model):
# The model fields
def get_absolute_url(self):
# reverse expects the view name
return reverse('feedback')
The absolute URL for any Feedback object will be the view FeedbackSendForm. That is specified by passing the view name feedback to reverse.
Example Createview:
views.py:
class FeedbackSendForm(CreateView):
model = Feedback
fields = ['title','text','user_name','user_lastname','email',]
template_name = 'feedback.html'
form_class = form_name
def form_valid(self, form):
"""
If the form is valid, redirect to the supplied URL.
"""
return HttpResponseRedirect(self.get_success_url())
"""
define `get_success_url' to your model or use `get_absolute_url` instead.
More information: class CreateView
If we define get_absolute_url in the model class then, while posting the form, we can leave the action tag as empty like this:
<form action="" method="post">
In this case, it now searches for the get_absolute_url in our model class defined as below:
def get_absolute_url(self):
return reverse("post_detail", kwargs={"pk": self.pk})
After updating or adding data in the model, our page is redirected to the URL named as post_detail.

Bringing Information from django.contrib.auth.models.User into View

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 %}

Categories

Resources