Why Django form is not rendering on my site? - python

What I want to do: I want to have a login form that when details are entered they are saved on the admin side.
My problem: the forms are not showing up on my local host page. See image below:
Here is the code from the login form app:
admin.py:
from django.contrib import admin
# Register your models here.
from .models import Contact
admin.site.register(Contact)
from apps.py:
from django.apps import AppConfig
class ContactConfig(AppConfig):
name = 'contact'
from forms.py
from .models import Contact
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
fields = ('username', 'password')
from models.py:
class Contact(models.Model):
username = models.CharField(max_length=100)
password = models.CharField(
max_length=100,
)
def __str__(self):
return f'{self.username} {self.password}'
from views.py:
# Create your views here.
from .forms import ContactForm
def contact(request):
template = "home2.html"
if request.method == "POST":
form = ContactForm(request.POST)
if form.is_valid():
form.save()
else:
form = ContactForm()
context = {
'form': form,
}
return render(request, template, context)
Then finally from the login page:
{% load static %}
<form method="post" class="form">
{% csrf_token %}
{{ form }}
<button type="submit" class="btn">Log In</button>
</form>
Another thing: forms are connected to the admin side but just do not appear on the login page

Related

Attribute error: 'AnonymousUser' object has no attribute '_meta'

I'm quite new to python and django. Here is my little project and this is the error message I get when I'm trying to log in as a user to my account. I have tried all the solutions which I gained by searching. Please if you know the solution explain it to me quite simply.
My log in view
def login_view(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST, request=request)
if form.is_valid:
user = form.user_cache
login(request, user)
return redirect('accounts:user-home')
else:
form = AuthenticationForm()
return render(request, 'login.html', {'form':form})\
My forms.py
# import form class from django
from django.forms import ModelForm
# import GeeksModel from models.py
from .models import *
from django.contrib.auth.models import User
# create a ModelForm
class ProfileForm(ModelForm):
# specify the name of model to use
class Meta:
model = Profile
exclude = [
'user',
]
class UsernameChangeForm(ModelForm):
class Meta:
model = User
fields = ['username', ]
My login.html
<h2>Log In</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Log In</button>
</form>
<p>Don't have an account yet? Register</p>

Django form: phone field not showing

I would like to create a contact form on my Django website.
For now, this is my code:
models.py:
from django.db import models
from phonenumber_field.modelfields import PhoneNumberField
class Client(models.Model):
phone = PhoneNumberField(null=False, blank=True, unique=True)
forms.py:
from django import forms
from phonenumber_field.modelfields import PhoneNumberField
class ContactForm(forms.Form):
fullName = forms.CharField(max_length=100)
email = forms.EmailField()
phone = PhoneNumberField()
message = forms.CharField(widget=forms.Textarea)
views.py:
def contact(request):
# return render(request, 'contact.html')
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# send email code goes here
return HttpResponse('Thanks for contacting us!')
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})
html:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
I of course installed phonenumber_field and added it in settings.py
This is the result, phone field missing:
Any help is hugely appreciated! Thanks for your time.
You used a model field, whereas for a form, you need a form field:
from django import forms
# a form field &downarrow;
from phonenumber_field.formfields import PhoneNumberField
class ContactForm(forms.Form):
fullName = forms.CharField(max_length=100)
email = forms.EmailField()
phone = PhoneNumberField()
message = forms.CharField(widget=forms.Textarea)

Django not rendering form fields

I looked at similar questions but they do not seem to apply. I have a very simple django form which does not show on the website, I only see the Submit button. Here are the relevant files:
models.py
from django.db import models
from django.urls import reverse
import uuid
# Create your models here.
class Job(models.Model):
id = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False)
job_name = models.CharField(max_length=200)
#One to many relationship requires on_delete
email = models.EmailField()
def __str__(self):
return self.job_name
forms.py
from django import forms
class JobForm(forms.Form):
job_name = forms.CharField(max_length=200)
email = forms.EmailField()
views.py
from django.shortcuts import render
from django.views.generic import TemplateView
from .forms import JobForm
from .models import Job
class HomePageView(TemplateView):
template_name = 'index.html'
class SubmitPageView(TemplateView):
template_name = 'submit.html'
def submit_job(request):
# Retrieve post by id
if request.method == 'POST':
# Form was submitted
form = JobForm(request.POST)
if form.is_valid():
#Form fields passed validation
#If the form is valid, we retrieve the validated data accessing
#form.cleaned_data. This attribute is a dictionary of form fields and their values.
cd = form.cleaned_data
my_model = Job()
my_model.job_name = cd.get('job_name')
my_model.email = cd.get('email')
# Save the job to the database
my_model.save()
else:
form = JobForm()
return render(request, SubmitPageView(), {'form': form})
And in my template I have
<form method="POST" action=".">
<table>
{% csrf_token %}
{{ form.as_table }}
</table>
which gets rendered as:
<form method="POST" action=".">
<table>
<input type="hidden" name="csrfmiddlewaretoken" value="I7yL9XAUhEPiriKVHKtqh9UfhsLWoJrBo68uguqMecX8gmuNoJV7gykvsPc7FtQ2">
</table>
OK, I found the solution by following https://docs.djangoproject.com/en/3.0/topics/class-based-views/intro/
Basically, as I was using class-based views, the functions to get and post the form need to be subsumed into the class-based view for that page. Here is the current version
of views.py:
from django.shortcuts import render
from django.views.generic import TemplateView
from .forms import JobForm
from .models import Job
class HomePageView(TemplateView):
template_name = 'index.html'
class SubmitPageView(TemplateView):
form_class = JobForm
template_name = 'submit.html'
def get(self, request, *args, **kwargs):
form = self.form_class()
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
#Form fields passed validation
#If the form is valid, we retrieve the validated data accessing
#form.cleaned_data. This attribute is a dictionary of form fields and their values.
cd = form.cleaned_data
my_model = Job()
my_model.job_name = cd.get('job_name')
my_model.email = cd.get('email')
# Save the job to the database
my_model.save()
else:
form = JobForm()
return render(request, self.template_name, {'form': form})
Try code below:
# if a GET (or any other method) we'll create a blank form
else:
form = JobForm()
return render(request, 'submit.html', {'form': form})
<form action="/your-name/" method="post">
{% csrf_token %}
{{ form.as_table }}
<input type="submit" value="Submit">
</form>
Does it make a difference if you define the form as a modelForm and explicitly state the model and fields?
Add/modify the following to your Forms.py:
class JobForm(forms.ModelForm):
class Meta:
model = Job
fields = ('job_name', 'email')
job_name = forms....

Link Username To Post Created By User

I would like to link the user who created the post by their username that way people know who it was posted by but I can't seem to get it to work and yes I am logged in and I have a working register and login form already.
Every time I go to submit some news from the form when logged in I get this error NOT NULL constraint failed: news_news.author_id
models.py
from django.db import models
from django.contrib.auth.models import User
from markdownx.models import MarkdownxField
from markdownx.utils import markdownify
from taggit.managers import TaggableManager
class News(models.Model):
author = models.ForeignKey(User, unique=True, on_delete=models.CASCADE)
title = models.CharField(max_length=150)
short_desc = models.CharField(max_length=500)
content = MarkdownxField()
tags = TaggableManager()
slug = models.SlugField(unique=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
views.py
from django.shortcuts import render, redirect, get_object_or_404
from .models import Category, News
from .forms import NewNewsForm
from django.shortcuts import render
def show_news_view(request):
news = News.objects.values('author', 'title', 'short_desc', 'tags', 'created_at', 'updated_at')
context = {
'news': news
}
return render(request, "news/news_home.html", context)
def new_news_form_view(request):
if request.method == "POST":
form = NewNewsForm(request.POST or None)
if form.is_valid():
form.save()
form = NewNewsForm()
return redirect('/news')
else:
form = NewNewsForm()
context = {
'form': form
}
return render(request, "news/news_form.html", context)
EDIT:
forms.py
from django import forms
from .models import News
class NewNewsForm(forms.ModelForm):
class Meta:
model = News
fields = ['title', 'short_desc', 'content', 'category', 'tags', 'slug']
news_form.html
{% extends "base.html" %}
{% block content %}
{% if user.is_authenticated %}
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
{% else %}
<p>Please login before you can submit a news story.</p>
{% endif %}
{% endblock content %}
You are not passing the user.
Later edit with a simpler solution:
Simply pass commit=False when saving the form. Which will create your News object without commiting it to DB. Simply set the author afterwards and save the object.
def new_news_form_view(request):
if request.method == "POST":
form_data = request.POST or None
form = NewNewsForm(form_data)
if form.is_valid():
news = form.save(commit=False)
news.author = request.user
news.save()
return redirect('/news')
else:
form = NewNewsForm()
context = {
'form': form
}
return render(request, "news/news_form.html", context)

how to make a register page accept only one email address

I just want to know how to make a register page accept one email address
I have not tried anything yet
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request, f'Your account has been created! You are now able to log in')
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html', {'form': form})
I want the register page to accept only one email address so it is used only once to register
Make sure this is the code in Django to make a register page!!!
models.py
from django.db import models
class Register(models.Model):
class Meta:
verbose_name_plural = 'Register'
email = models.EmailField()
forms.py
from django import forms
from index.models import *
class Registerform(forms.ModelForm):
class Meta:
model = Register
fields = '__all__'
views.py
from index import forms as formlocal
def register(request):
form = formlocal.Registerform()
if request.method == 'POST':
form = formlocal.Registerform(request.POST)
some_var = request.POST.getlist('role')
if form.is_valid():
form.save(commit=True)
return render(request,'index/register.html',{'form':form})
urls.py
from django.urls import path, include
from index import views as ind
urlpatterns = [
path('register/', ind.register,name='joincoc'),
]
template - index/register.html
<form method="POST">
<div>
{{ form.errors }}
</div>
<div>
{{ form.email}}
</div>
{% csrf_token %}
<button type="submit" name="submit">Submit</button>
</form>

Categories

Resources