Using Django and Postgres to store phone numbers - python

I currently want to make a web app in django with a form that asks a user to input a phone number and submit, and I want that number they submit to be stored in a database using postgres. I'm having a hard time finding information on how to use post requests in django to connect to postgres.
index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test Form 1</title>
</head>
<body>
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Send message">
</form>
</body>
</html>
admin.py
from django.contrib import admin
from .models import Post
admin.site.register(Post)
urls.py
from django.contrib import admin
from django.urls import path
# from main.views import first
from main import views as test_app_views
urlpatterns = [
path('admin/', admin.site.urls),
# path('', first)
path('', test_app_views.FormView1.as_view())
]
forms.py
from django import forms
from phone_field import PhoneField
from main.models import Post
class HomeForm(forms.ModelForm):
phone = PhoneField()
class Meta:
model = Post
fields = ('phone',)
models.py
from django.db import models
from phone_field import PhoneField
from django.contrib.auth.models import User
class Post(models.Model):
phone = PhoneField()
user = models.ForeignKey(User, on_delete=models.CASCADE,)
views.py
from django.shortcuts import render
from django.views.generic.edit import FormView
from .forms import HomeForm
class FormView1(FormView):
template_name = 'index.html'
# form_class = RequiredInputsForm
# success_url = '/index/success/'
def get(self, request):
form = HomeForm()
return render(request, self.template_name, {'form': form})
def post(self, request):
form = HomeForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.user = request.user
post.save()
phone = form.cleaned_data['post']
form = HomeForm()
return redirect('index:index')
args = {'form': form, 'text': text}
return render(request, self.template_name, args)
How can I get this to store the phone number in the postgres db after I've initialized the project to use it? This was what I tried but I am consistently getting the error: 'ValueError at /
Cannot assign ">": "Post.user" must be a "User" instance.'
I think what I'm trying to do is quite simple, I've just never done it before with django and postgres, any help would be appreciated!

Related

correct using get_or_create?

To my code, which records a contact from the form and adds it to the db, need to add get_or_create, or write another condition (if there is a contact with such a phone — update, no - add), but i'm do it for the first time, please, I'll be glad to read solution to my problem and a brief explanation ♡
views.py
from django.http import HttpResponse
from django.shortcuts import render,redirect
from django.contrib import messages
from .forms import Forms
def main(request):
form = Forms
if request.method == "POST":
form = Forms(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Form has been submitted')
return redirect('/')
return render(request, 'app/main.html', { 'form':form } )
forms.py
from django.forms import ModelForm
from .models import Form
class Forms(ModelForm):
class Meta:
model = Form
fields = '__all__'
urls.py
from django.contrib import admin
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('app.urls'))
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
models.py
from django.db import models
class Form(models.Model):
name = models.CharField(max_length=30)
phone = models.CharField(max_length=30)
admin.py
from django.contrib import admin
from .models import Form
'''from django.contrib.admin.models import LogEntry
LogEntry.objects.all().delete()'''
'''for delete actions in admin_panel'''
admin.site.register(Form)
apps.py
from django.apps import AppConfig
class AppConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'app'
main.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTE-8">
<meta name="viewport" content="width, initial-scale=1.0">
<title>CHECK DATA</title>
</head>
<body>
{% for message in messages %}
<p>{{message}}</p>
{% endfor %}
<form action="" method="post">
{% csrf_token %}
<table>
{{form.as_table}}
<tr>
<td colspan="2">
<input type="submit"/>
</td>
</tr>
</table>
</form>
</body>
</html>
You can implement this with:
def main(request):
if request.method == "POST":
form = Forms(request.POST)
if form.is_valid():
Form.objects.get_or_create(
phone=form.cleaned_data['phone'],
defaults={'name': form.cleaned_data['name']}
)
messages.success(request, 'Form has been submitted')
return redirect('/')
else:
form = Forms()
return render(request, 'app/main.html', { 'form': form })
You must be careful however since this means that a user might edit data of another user. Perhaps it is thus worth to check if the (logged in) user has rights to update that item.

Form preview in Django

I am building a registration form. Whenever a user fills the form and clicks the register button I want them to see the preview of their submissions. I am having problems with the arguments. Here goes my code:
models.py
from django.db import models
from phonenumber_field.modelfields import PhoneNumberField
# Create your models here.
class Register(models.Model):
regChoice = (
('Self', 'Self'),
('Group', 'Group'),
('Corporate', 'Corporate'),
('Others', 'Others'),
)
name = models.CharField(max_length=50)
email = models.EmailField(max_length=254,null=True)
phoneNumber = PhoneNumberField(null=True)
idCard = models.ImageField(null=True)
regType = models.CharField(max_length=25, choices=regChoice,null=True)
ticketNo = models.IntegerField(default=1)
def __str__(self):
return self.name
forms.py
from django import forms
from django.forms import ModelForm
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import *
class RegisterForm(ModelForm):
name = forms.CharField(widget=forms.TextInput(attrs={'placeholder':'Your full name...'}))
email = forms.CharField(widget=forms.TextInput(attrs={'placeholder':'Your email...'}))
phoneNumber = forms.CharField(widget=forms.TextInput(attrs={'placeholder':'Your phone number...'}))
class Meta:
model = Register
fields = '__all__'
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='home'),
path('preview.html/<str:pk>', views.preview, name="preview")
]
views.py
from django.shortcuts import render, redirect
from .models import *
from .forms import *
# Create your views here.
def index(request):
form = RegisterForm()
if request.method == 'POST':
form = RegisterForm(request.POST, request.FILES)
if form.is_valid():
form.save()
context = {'form':form}
return render(request, 'event/index.html', context)
def preview(request, pk):
reg = Register.objects.get(id=pk)
prev = RegisterForm(instance=reg)
if request.method == 'POST':
form = RegisterForm(request.POST, instance=reg)
if form.is_valid():
form.save()
return redirect('/')
context = {'reg':reg, 'prev':prev}
return render(request, 'event/preview.html', context)
index.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Event Registration</title>
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<script src="{% static 'js/script.js' %}"></script>
</head>
<body>
<div class="mobile-screen">
<div class="header">
</div>
<div class="logo"></div>
<form id="login-form" method="POST" action="{% url 'preview' form.id %}" enctype="multipart/form-data">
{% csrf_token %}
{{form.name}}
{{form.email}}
{{form.phoneNumber}}
<legend style="color: aliceblue;">Upload ID card: </legend>{{form.idCard}}
<div style="text-align: center; color: aliceblue;">Registration Type: {{form.regType}}</div>
{{form.ticketNo}}
<input class="btn btn-sm btn-primary" type="submit" value="Register" name="Register">
</form>
</div>
</body>
</html>
preview.html
Hello {{prev.name}},
your email is {{prev.email}}
your phone number is {{prev.phoneNumber}}
your idCard photo is {{prev.idCard.url}}
your registration type is {{prev.regType}}
your number of tickets is {{prev.ticketNo}}
The error I am having is:
NoReverseMatch at /
Reverse for 'preview' with arguments '('',)' not found. 1 pattern(s) tried: ['preview\.html/(?P[^/]+)$']
When someone reaches your index page and enters the form we need to
Submit the form as a POST request to index view
Save the form thereby creating a model in the DB
Redirect the user to preview view using the above id
To do that the code needs to be somewhat like this, I have not tested it, but you should get the idea.
from django.shortcuts import redirect
def index(request):
form = RegisterForm()
if request.method == 'POST':
form = RegisterForm(request.POST, request.FILES)
if form.is_valid():
instance = form.save()
return redirect('preview', pk=instance.id)
context = {'form':form}
return render(request, 'event/index.html', context)
Inside your index.html change
action="{% url 'preview' form.id %}"
to
action=""
as we want it to post to the INDEX view as that is where out POST handling logic is.
The index view then redirects to preview using the newly generated object.
Also as mentioned by #Snir in the other answer, having .html in URLS is not a standard practice. It would be better to simple make it something like:
path('preview/<str:pk>', views.preview, name="preview")
The URL patterns are regexes, so you'll have to escape special regex characters, like the dot. Try (add r) or remove the dot:
path(r'preview.html/<str:pk>', views.preview,
name="preview")

Django 2.2 Cannot figure out how to authorize user to edit or delete blog post if user created that blog post

So this is the third time I'm asking this question. I don't know how to allow only a user, that created a particular blog post, to edit or delete that post. So this blog is like any other blog. All users can look at all other users blog posts. To create a blog post, a user must be logged in with an account already. Same thing for edit and delete a blog post. However, I don't know how to check to see if a user can edit or delete a blog post based off whether that user was the one that created the blog post or not. I'm typing this question since no one answered my previous questions I posted. below are three files for models, views, and the html for update/edit a blog post. I can figure out the delete once I figure out the edit. I know Django creates add, change, delete permissions automatically. Unfortunately, the change and delete permissions always return false, even if that user is already logged in. I've been stuck on this for days. Like 15+ hours already over three days.
blog/models.py
from django.db import models
from django.conf import settings
from django.utils import timezone
from django.db.models import Q
User = settings.AUTH_USER_MODEL
class BlogPostQuerySet(models.QuerySet):
def published(self):
now = timezone.now()
return self.filter(publish_date__lte=now)
def search(self, query):
lookup = (
Q(title__icontains=query) |
Q(content__icontains=query) |
Q(slug__icontains=query) |
Q(user__first_name__icontains=query) |
Q(user__last_name__icontains=query) |
Q(user__username__icontains=query) |
Q(user__email__icontains=query) |
Q(image__icontains=query)
)
return self.filter(lookup)
class BlogPostManager(models.Manager):
def get_queryset(self):
return BlogPostQuerySet(self.model, using=self._db)
def published(self):
return self.get_queryset().published()
def search(self, query=None):
if query is None:
return self.get_queryset().none()
return self.get_queryset().published().search(query)
class BlogPost(models.Model): # blogpost_set -> queryset
user = models.ForeignKey(User, default=1, null=True, on_delete=models.SET_NULL)
image = models.ImageField(upload_to='image/', blank=True, null=True)
title = models.CharField(max_length=120)
slug = models.SlugField(unique=True) # Example: "hello world" -> hello-world
content = models.TextField(null=True, blank=True)
publish_date = models.DateTimeField(auto_now=False, auto_now_add=False, null=True, blank=True)
timestamp = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
objects = BlogPostManager()
class Meta:
ordering = ['-publish_date','-updated','-timestamp']
permission = (
("can_change_blogpost", "Can change BlogPost"),
)
def get_absolute_url(self):
return f"/blog/{self.slug}"
def get_edit_url(self):
return f"{self.get_absolute_url()}/edit"
def get_delete_url(self):
return f"{self.get_absolute_url()}/delete"
blog/views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, get_object_or_404
from .models import BlogPost
from .forms import BlogPostModelForm
from django.contrib.auth.models import User
def blog_post_list_view(request):
qs = BlogPost.objects.all().published() # queryset -> list of python objects
if request.user.is_authenticated:
my_qs = BlogPost.objects.filter(user=request.user)
qs = (qs | my_qs).distinct()
context = {'object_list':qs}
return render(request, 'blog/list.html', context)
#login_required
def blog_post_create_view(request):
form = BlogPostModelForm(request.POST or None, request.FILES or None)
if form.is_valid():
obj = form.save(commit=False)
obj.user = request.user
obj.save()
form = BlogPostModelForm()
context = {'form':form}
return render(request, 'blog/form.html', context)
def blog_post_detail_view(request, slug):
obj = get_object_or_404(BlogPost, slug=slug)
context = {'object':obj}
return render(request, 'blog/detail.html', context)
#login_required
def blog_post_update_view(request, slug):
obj = get_object_or_404(BlogPost, slug=slug)
form = BlogPostModelForm(request.POST or None, instance=obj)
if form.is_valid():
form.save()
context = {
"form":form,
"title":f"Update {obj.title}",
}
return render(request, 'blog/update.html', context)
#login_required
def blog_post_delete_view(request, slug):
obj = get_object_or_404(BlogPost, slug=slug)
if request.method == "POST":
obj.delete()
context = {'object':obj}
return render(request, 'blog/delete.html', context)
blog/templates/blog/update.html
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'blog/style.css' %}">
<title>New Blog post</title>
</head>
<body>
<div class="parallax5" align="center">
<h1 class="a">UPDATE your Blog page</h1><br>
<h1>Perms</h1><br>
{{ perms.blog.change_blogpost }}<br>
{% if perms.blog.change_blogpost %}
<form style="background-color:grey;" method="POST" action=".">
<p>Please only post blogs that are in good taste. You can
update your blog below.</p>
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Update Blog</button>
</form><br>
{% else %}
<p style="background-color:red;color:white;">You do not have permission to update this blog post</p>
{% endif %}
<a style="background-color:white;font-size:50px;" href="{% url 'list' %}">I'm done!<br>Go back to blog list</a>
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
WHAT I'VE TRIED SO FAR...
Everything! You name it, I already (very highly likely) know what you're talking about. I'm too tired and angry to even go over the big list of everything I've tried. Please someone help!
My site does have exactly the same behaviour you're asking for but with quite the different implementation.
Post Delete View looks like this:
class PostDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Post
success_url = '/market'
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
Post Update View:
class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Post
fields = ['title', 'content']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
for this code to work you would also need to import these:
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.views.generic import ( ListView, DetailView, CreateView, UpdateView, DeleteView)
I know, just showing you my code base might not help you directly but it might give you some ideas, let me know. And stay strong, I know it can get frustrating sometimes, but you will manage it.

model forms fiels not displayed in views in django

The problem is that the first_name, last_name and email fields are not displayed in browser. The command prompt is showing no error and server is running smoothly.
I cant figure out whats the problem.Here is my code.I am using django 1.11 and python 3.6
models.py
from django.db import models
# Create your models here.
class signup(models.Model):
first_name=models.CharField(max_length=120,null=True,blank=True)
last_name=models.CharField(max_length=120,null=True,blank=True)
email=models.EmailField()
timestamp=models.DateTimeField(auto_now_add=True,auto_now=False)
updated=models.DateTimeField(auto_now_add=False,auto_now=True)
def __str__(self):
return self.email
forms.py
from django import forms
from .models import signup
class sign_up_form(forms.ModelForm):
class Meta:
model = signup
fields='__all__'
views.py
from django.shortcuts import render,render_to_response
from django.template import RequestContext
from .forms import sign_up_form
# Create your views here.
def home(request):
form = sign_up_form()
return render(request,'signup.html',)
signup.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>join now</h1>
<form method="POST" action="">{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
</body>
</html>
I think you omitted to include your form in the template context, inside the render method (note that the default context parameter is None).
def home(request):
form = sign_up_form()
return render(request,'signup.html', {'form': form})
Also, as per PEP8 style guide, please name your classes as CamelCase (SignUpForm for your form, SignUp for your model etc.).

Validating the form without required field in django 1.8

My django modelform is letting the user submit the form without raising error even when the user hasn't submitted appropriate form, here it lets the user keep the email field blank.It doesn't save into the database because of is_valid() but the page refreshes and form goes blank again... Here is the code
models.py
from django.db import models
class MainForm(models.Model):
text = models.CharField(max_length=100)
email = models.EmailField(blank=False)
name = models.CharField(max_length=100,blank=False)
def __unicode__(self):
return self.email
forms.py
from django import forms
from .models import MainForm,new_model
class form_MainForm(forms.ModelForm):
class Meta:
model = MainForm
fields = '__all__'
views.py
def view_MainForm(request):
context = {
"form": form_MainForm
}
if request.method == 'POST' :
form_instance = form_MainForm(request.POST or None)
if form_instance.is_valid():
form_instance.save()
return render(request,'done.html',{'text':form_instance.cleaned_data.get('email')})
return render(request,'main_form.html',context)
template ->main_form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Main Form</title>
</head>
<body>
<form method="post" action=".">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
</body>
</html>
Your view function is wrong - you have to pass the invalid form to the context to get the error messages, ie:
def view_MainForm(request):
if request.method == 'POST' :
form_instance = form_MainForm(request.POST)
if form_instance.is_valid():
form_instance.save()
# here you should redirect to avoid
# re-submission of the form on page reload
# cf https://en.wikipedia.org/wiki/Post/Redirect/Get
return render(request,'done.html',{'text':form_instance.cleaned_data.get('email')})
else:
form_instance = form_MainForm()
context = {"form": form_instance}
return render(request,'main_form.html',context)
check this link to render error in your form https://docs.djangoproject.com/en/1.10/topics/forms/#rendering-form-error-messages , this will give an idea like why you are not able to save data.
when you are sending back the form it should be
context = {"form": form_MainForm(request.POST)} , this will display the form submitted values

Categories

Resources