How I can replace user id to username in django JSON? - django

I'm writing a simple chat with ajax and I have a problem with JSON. I need username instead of id.
JSON seems like:
[{"pk": 41, "model": "chat.post", "fields": {"timestamp": "2012-01-27 22:14:46", "user": 1, "text": "weq"}}]`
I need replace "user": 1 to "user": username.
How I can do it?
My model:
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
timestamp = models.DateTimeField(auto_now_add=True)
text = models.TextField()
user = models.ForeignKey(User)
class Meta:
ordering = ['-id']
def __unicode__(self):
return "[%s] %s by user: %s" % (
self.timestamp.strftime("%Y-%m-%d %H:%M:%S"),
self.text,
self.user
)
My view:
# -*- coding: utf-8 -*-
#!/usr/bin/env python
from django.http import HttpResponse
from django.core import serializers
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.template import RequestContext
from django.shortcuts import render_to_response
from live.chat.models import Post
#login_required
def updates_after(request, id):
response = HttpResponse()
response['Content-Type'] = "text/javascript"
response.write(serializers.serialize("json",
Post.objects.filter(pk__gt=id)))
# __gt - greaten then > id
return response
#login_required
def saymessage(request):
if request.method == 'POST':
if "text" in request.POST:
text = request.POST["text"]
user = request.user
message = Post()
message.user, message.text = user, text
message.save()
return HttpResponseRedirect('/')
else:
pass
JSON response example:
[
{
"pk": 42,
"model": "chat.post",
"fields": {
"timestamp": "2012-01-28 18:08:44",
"user": 1,
"text": "dasd"
}
}
]
My template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
Remove this if you use the .htaccess -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>templates</title>
<meta name="description" content="" />
<script type="text/javascript" language="javascript" src="/media/js/jquery.min.js"></script>
<script type="text/javascript" language="javascript">
function update() {
update_holder = $("#update_holder");
most_recent = update_holder.find("div:first");
$.getJSON("/live/updates-after/" + most_recent.attr('id') + "/",
function(data) {
cycle_class = most_recent.hasClass("odd") ? "even" : "odd";
jQuery.each(data, function(){
update_holder.prepend('<div id="' + this.pk
+ '" class="update ' + cycle_class
+ '"><div class="timestamp">'
+ this.fields.timestamp
+ '</div><div class="user">'
+ this.fields.user
+ '</div><div class="text">'
+ this.fields.text
+ '</div><div class="clear"></div></div>'
);
cycle_class = (cycle_class == "odd") ? "even" : "odd";
});
}
);
}
$(document).ready(function() {
setInterval("update()", 10000);
})
</script>
<link rel="stylesheet" type="text/css" href="/media/css/main.css" />
</head>
<body>
{% block content %}
<div>
<header>
<h1>Live Update site</h1>
<p>Содержимое обновляется автоматически</p>
</header>
{% if object_list %}
<div id="update_holder">
{% for object in object_list %}
<div class="update {% cycle even,odd %}" id="{{ object.id }}">
<div class="timestamp">
{{ object.timestamp|date:"Y-m-d H:i:s" }}
</div>
<div class="user">
{{ object.user }}
</div>
<div class="text">
{{ object.text|linebreaksbr }}
</div>
<div class="clear"></div>
</div>
{% endfor %}
</div>
{% else %}
<p>Нет обновлений</p>
{% endif %}
</div>
<form enctype="multipart/form-data" action="{% url chat.views.saymessage %}" method="post">{% csrf_token %}
Введите текст сообщения: <input type="text" name="text" id="text">
<input type="submit" name="submit" value="Отправить">
</form>
{% endblock %}
</body>
</html>
Update:
I figure out this problem, we need using natural_key(), and overrive this method in user manager class, add next code to models.py:
class UserManager(models.Manager):
def unatural_key(self):
return self.username
User.natural_key = unatural_key
And dont forget add argument use_natural_keys=True to serializers.serialize()

You might want to look into Natural Keys. Natural keys allow you to specify what foreign key fields are serialized to. By constructing a primary key for your user, you can have the username in the serialization, instead of the ID.

You should change this method to
def __unicode__(self):
return "[%s] %s by user: %s" % (
self.timestamp.strftime("%Y-%m-%d %H:%M:%S"),
self.text,
self.user.username
)
But this is a dirty solution. Your view updates_after is very ugly. I would change updates_after. See a similar view

Related

django: taking user input from html, processing it and showing output in the same page

I am quite new in Django and stuck at specific point. I want to take user input from html that goes into database, process it with specific python script and return result to the same html page.
I want Users to enter score in "exam_score" line, then process that input with specific python script and then to output result to "uni_name_1_result". For now, python script that just prints 'Hello world' is enough, just want to understand the mythology of how it can be done.
Would appreciate any help.
models.py
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
# Create your models here.
class User(models.Model):
first_name = models.CharField(max_length=128)
last_name = models.CharField(max_length=128)
email = models.EmailField(max_length=254,unique=True)
exam_score = models.FloatField(null=True, validators=[MinValueValidator(0.0),MaxValueValidator(700)])
uni_name_1 = models.CharField(max_length=254)
uni_name_1_result = models.CharField(max_length=254)
forms.py
from django import forms
from django.core import validators
from ielts_app.models import User
class NewUserForm(forms.ModelForm):
# validations can be set here
class Meta():
model = User
fields = '__all__'
views.py
from django.shortcuts import render
# from ielts_app import forms
from ielts_app.forms import NewUserForm
# from django.http import HttpResponseRedirect
def index(request):
return render(request,'ielts_app/index.html')
def users(request):
form = NewUserForm()
if request.method == 'POST':
form = NewUserForm(request.POST)
if form.is_valid():
variable:form.cleaned_data
form.save(commit=True) # to save forum data (user data), commit=True to database
# return HttpResponseRedirect('/THANKS/')
return index(request) # return back to homeage after getting user data
else:
print("ERROR!")
return render(request,'ielts_app/users.html',{'form':form})
users.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Users</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<h1>Please Sign Up:</h1>
<div class="container">
<form method="POST">
{{ form.as_p }}
{% csrf_token %}
<input type="submit" class='btn btn-primary' value="Submit">
</form>
</div>
</body>
</html>
You can do following way.
from django import forms
from django.core import validators
from ielts_app.models import User
class NewUserForm(forms.ModelForm):
# validations can be set here
class Meta():
model = User
fields = ('exam_score',)
And in your user.html do this.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Users</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<h1>Please Sign Up:</h1>
<div class="container">
<form method="POST">
{% for field in form %}
{{ form.as_p }}
{{ field }}
{% endfor %}
{% csrf_token %}
<input type="submit" class='btn btn-primary' value="Submit">
</form>
</div>
</body>
</html>
It is better you rename your model to some other model name as it may collide with User Model given by django.

Stripe payment - Why when I call if payment_form.is_valid(): is it always invalid?

I am trying to take a Stripe payment but every time the function is_valid() returns false and the message "We were unable to take a payment with that card!" is displayed.
The payment is for a set amount of 5 Euros. I am using the credit card number 4242 4242 4242 4242 to test the payment.
The terminal states that the 'stripe_id' is required but I am at a loss as to what to do about that.
Can anyone help me find what is wrong with my code?
checkout.html:
{% extends "base.html" %}
{% load static from staticfiles %}
{% load bootstrap_tags %}
{% block head_js %}
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<script type="text/javascript" src="">
//<![CDATA[
Stripe.publishableKey = '{{ publishable }}';
// ]]>
</script>
<script type="text/javascript" src="{% static 'js/stripe.js' %}"></script>
{% endblock %}
{% block content %}
<form action="{% url 'checkout' %}" method="post" id="payment-form" class="col-md-6 col-md-offset-3">
<legend>Payment Details</legend>
<div id="credit-card-errors" style="display: none;">
<div class="alert-message block-message error" id="stripe-error-message"></div>
</div>
<div class="form-group col-md-6">
{{ payment_form|as_bootstrap }}
</div>
{% csrf_token %}
<div class="form-group col-md-12">
<input class=" btn btn-primary" id="submit_payment_btn" name="commit" type="submit" value="Submit Payment of 5 Euros">
</div>
</form>
{% endblock %}
forms.py:
from django import forms
class MakePaymentForm(forms.Form):
print("MakePaymentForm...")
MONTH_CHOICES = [(i, i) for i in range(1, 12)]
YEAR_CHOICES = [(i, i) for i in range(2019, 2040)]
credit_card_number = forms.CharField(label='Credit Card Number', required=False)
cvv = forms.CharField(label ='Security Code (CVV)', required=False)
expiry_month = forms.ChoiceField(label="Month",choices=MONTH_CHOICES, required=False)
expiry_year = forms.ChoiceField(label='year',choices=YEAR_CHOICES, required=False)
stripe_id = forms.CharField(widget=forms.HiddenInput, required=False)
views.py:
from django.shortcuts import render, get_object_or_404, redirect, reverse
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .forms import MakePaymentForm
from tickets.forms import TicketsForm
from tickets.models import Ticket
from django.conf import settings
from accounts.views import login, index
from django.utils import timezone
import stripe
# Create your views here.
stripe.api_key = settings.STRIPE_SECRET
#login_required()
def checkout(request):
if request.method == "POST":
payment_form = MakePaymentForm(request.POST)
print("checkout...")
if payment_form.is_valid():
print("Payment form is valid...")
try:
print("Just about to charge the customer...")
customer = stripe.Charge.create(
amount=500,
currency="EUR",
description="Thank you for your contribution, it will really help our site" and request.user.email,
card=payment_form.cleaned_data['stripe_id']
)
except stripe.error.CardError:
messages.error(request, "Your card was declined!")
if customer.paid:
print("Customer has paid...")
messages.error(request, "You have successfully paid")
return redirect(reverse('index'))
else:
messages.error(request, "Unable to take payment")
return redirect(reverse('index'))
else:
print("There are errors...")
print(payment_form.errors)
messages.error(request, "We were unable to take a payment with that card!")
else:
print("Method isn't post...")
payment_form = MakePaymentForm()
return render(request, "checkout.html", {"payment_form": payment_form, "publishable": settings.STRIPE_PUBLISHABLE})
Here is the output in the terminal:
[14/Dec/2020 22:47:40] "GET /checkout/ HTTP/1.1" 200 5688
checkout...
There are errors...
<ul class="errorlist"><li>stripe_id<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
[14/Dec/2020 22:47:51] "POST /checkout/ HTTP/1.1" 200 5850
and here is stipe.js:
$(function(){
$("#payment-form").submit(function() {
console.log("#payment-form");
var form = this;
var card = {
number: $("#id_credit_card_number").val(),
expMonth: $("#id_expiry_month").val(),
expYear: $("#id_expiry_year").val(),
cvc: $("#id_cvv").val()
};
Stripe.createToken(card, function(status, response) {
console.log("#createToken");
if (status === 200) {
$("#credit-card-errors").hide();
$("#id_stripe_id").val(response.id);
// Prevent the credit card details from being submitted
// to our server
$("#id_credit_card_number").removeAttr('name');
$("#id_cvv").removeAttr('name');
$("#id_expiry_month").removeAttr('name');
$("#id_expiry_year").removeAttr('name');
form.submit();
} else {
$("#stripe-error-message").text(response.error.message);
$("#credit-card-errors").show();
$("#validate_card_btn").attr("disabled", false);
}
});
return false;
});
});
I have made and my form is now valid, but when it sends the payment request to Stripe I get the following error and it looks like stripe_id is blank. Any ideas?
InvalidRequestError at /checkout/1
InvalidRequestError at /checkout/2

Django stripe.error: Invalid card object: must be a dictionary or a non-empty string

I am trying to take a Stripe payment but I get an InvalidRequestError everytime I try to make a payment.
The payment is for a set amount of 5 Euros. I am using the credit card number 4242 4242 4242 4242 to test the payment.
My form is valid, but when it sends the payment request to Stripe I get the errors and it looks like stripe_id is blank. Any ideas?
checkout.html:
{% extends "base.html" %}
{% load static from staticfiles %}
{% load bootstrap_tags %}
{% block head_js %}
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<script type="text/javascript" src="">
//<![CDATA[
Stripe.publishableKey = '{{ publishable }}';
// ]]>
</script>
<script type="text/javascript" src="{% static 'js/stripe.js' %}"></script>
{% endblock %}
{% block content %}
<form action="{% url 'checkout' %}" method="post" id="payment-form" class="col-md-6 col-md-offset-3">
<legend>Payment Details</legend>
<div id="credit-card-errors" style="display: none;">
<div class="alert-message block-message error" id="stripe-error-message"></div>
</div>
<div class="form-group col-md-6">
{{ payment_form|as_bootstrap }}
</div>
{% csrf_token %}
<div class="form-group col-md-12">
<input class=" btn btn-primary" id="submit_payment_btn" name="commit" type="submit" value="Submit Payment of 5 Euros">
</div>
</form>
{% endblock %}
forms.py:
from django import forms
class MakePaymentForm(forms.Form):
print("MakePaymentForm...")
MONTH_CHOICES = [(i, i) for i in range(1, 12)]
YEAR_CHOICES = [(i, i) for i in range(2019, 2040)]
credit_card_number = forms.CharField(label='Credit Card Number', required=False)
cvv = forms.CharField(label ='Security Code (CVV)', required=False)
expiry_month = forms.ChoiceField(label="Month",choices=MONTH_CHOICES, required=False)
expiry_year = forms.ChoiceField(label='year',choices=YEAR_CHOICES, required=False)
stripe_id = forms.CharField(widget=forms.HiddenInput, required=False)
views.py:
from django.shortcuts import render, get_object_or_404, redirect, reverse
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .forms import MakePaymentForm
from tickets.forms import TicketsForm
from tickets.models import Ticket
from django.conf import settings
from accounts.views import login, index
from django.utils import timezone
import stripe
# Create your views here.
stripe.api_key = settings.STRIPE_SECRET
#login_required()
def checkout(request):
if request.method == "POST":
payment_form = MakePaymentForm(request.POST)
print("checkout...")
if payment_form.is_valid():
print("Payment form is valid...")
try:
print("Just about to charge the customer...")
customer = stripe.Charge.create(
amount=500,
currency="EUR",
description="Thank you for your contribution, it will really help our site" and request.user.email,
card=payment_form.cleaned_data['stripe_id']
)
except stripe.error.CardError:
messages.error(request, "Your card was declined!")
if customer.paid:
print("Customer has paid...")
messages.error(request, "You have successfully paid")
return redirect(reverse('index'))
else:
messages.error(request, "Unable to take payment")
return redirect(reverse('index'))
else:
print("There are errors...")
print(payment_form.errors)
messages.error(request, "We were unable to take a payment with that card!")
else:
print("Method isn't post...")
payment_form = MakePaymentForm()
return render(request, "checkout.html", {"payment_form": payment_form, "publishable": settings.STRIPE_PUBLISHABLE})
Here is the output in the terminal:
[14/Dec/2020 22:47:40] "GET /checkout/ HTTP/1.1" 200 5688
checkout...
There are errors...
<ul class="errorlist"><li>stripe_id<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
[14/Dec/2020 22:47:51] "POST /checkout/ HTTP/1.1" 200 5850
and here is stipe.js:
$(function(){
$("#payment-form").submit(function() {
console.log("#payment-form");
var form = this;
var card = {
number: $("#id_credit_card_number").val(),
expMonth: $("#id_expiry_month").val(),
expYear: $("#id_expiry_year").val(),
cvc: $("#id_cvv").val()
};
Stripe.createToken(card, function(status, response) {
console.log("#createToken");
if (status === 200) {
$("#credit-card-errors").hide();
$("#id_stripe_id").val(response.id);
// Prevent the credit card details from being submitted
// to our server
$("#id_credit_card_number").removeAttr('name');
$("#id_cvv").removeAttr('name');
$("#id_expiry_month").removeAttr('name');
$("#id_expiry_year").removeAttr('name');
form.submit();
} else {
$("#stripe-error-message").text(response.error.message);
$("#credit-card-errors").show();
$("#validate_card_btn").attr("disabled", false);
}
});
return false;
});
});
And here are the errors after I submit the payment:
InvalidRequestError 1
InvalidRequestError 2
The Terminal
I found the answer and the credit card payments are working fine now. I hadn't included the jQuery CDN in the header so stripe.js wasn't being called correctly!

My django form is not displaying on the html page

I am trying to create an addform to take input from a user and add it to my model, however, the form is not showing on the page, can someone tell me what I am doing wrong? Here is the code for the forms.py, views.py and add.html:
forms.py
class AddForm(forms.Form):
vehicle = forms.CharField(max_length=10)
carrier = forms.FloatField()
location = forms.ChoiceField(choices=[(1, 'Mathura Installation')])
customer_code = forms.FloatField()
zone = forms.ChoiceField(choices=[('NW', 'North West'),
('NCR', 'North Central'),
('SCR', 'South Central'),
('S', 'South'), ('N', 'North'),
('W', 'West'), ('E', 'East')
])
quantity = forms.FloatField()
load = forms.FloatField()
rtkm = forms.FloatField(label='RTKM')
rate = forms.ChoiceField(label='Rate ', widget=forms.RadioSelect, choices=[('avg', 'Average Rate'),
('user', 'User Rate')])
views.py
def add(request):
addform = forms.AddForm()
dict = {'addform': addform}
return render(request, 'add.html', dict)
urls.py
from django.contrib import admin
from django.urls import path
from searchapp import views
urlpatterns = [
path('', views.search, name='search'),
path('add/', views.add, name='add'),
path('admin/', admin.site.urls),
]
html - add.html
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
<head>
<meta charset="UTF-8">
<title>Transport Portal - Add Page</title>
</head>
<body>
<div class="header">
<img src="{% static 'images/hpcl_logo.png' %}">
<h1>Transportation Portal</h1>
</div>
<div class="topnav">
<ul>
<li>Home</li>
<li>Search</li>
<li><a class="active" href="add.html">Add</a></li>
</ul>
</div>
<div class="add">
<form method="POST">
{% csrf_token %}
{{ addform.as_p }}
</form>
</div>
</body>
</html>
I think the problem is how you're getting there.
You have the following in your html
<li><a class="active" href="add.html">Add</a></li>
This is going to pick up the html page but you want href="{% url 'add' %}" which will pick up the django url.
Instead of dict use context
def add(request):
addform = forms.AddForm()
context= {'addform': addform}
return render(request, 'add.html', context)
Please read this. context

Django form self validation not working

My urls.py is something like this :
from django.conf.urls import url
from django.views.generic import ListView, TemplateView
from .models import Dreamreal
from . import views
urlpatterns = [
url(r'^connection/login/$', views.login),
url(r'^connection/$', TemplateView.as_view(template_name =
'login.html')),
url(r'^login/$', views.login, name = 'login')
]
My views.py is :
from .forms import LoginForm
from . import models
def login(request):
username = "not logged in"
if request.POST:
# GET THE POSTED FORM
MyLoginForm = LoginForm(request.POST)
if MyLoginForm.is_valid():
username = MyLoginForm.cleaned_data['username']
else:
MyLoginForm = LoginForm()
return render(request, 'loggedin.html', {'username' : username})
My forms.py is :
from django import forms
from .models import Dreamreal
class LoginForm(forms.Form):
username = forms.CharField(max_length = 100)
password = forms.CharField(widget = forms.PasswordInput())
# METHOD TO VERIFY IF USER IS IN DB
def clean_message(self):
username = self.cleaned_data.get("username")
dbuser = Dreamreal.objects.filter(name = 'username')
if not dbuser:
raise forms.ValidationError("User does not exist in our db!")
return username
My models.py is :
from django.db import models
class Dreamreal(models.Model):
website = models.CharField(max_length = 50)
mail = models.CharField(max_length = 50)
name = models.CharField(max_length = 50)
phonenumber = models.IntegerField()
class Meta:
db_table = 'dreamreal'
My login.html is :
<html>
<head>
<title>LOG IN</title>
</head>
<body>
<form name="form" action="/connection/login/" method="POST">
{% csrf_token %}
<div style="max-width: 470px;">
<center><input type="text" name="username"
placeholder="username" style="margin-left: 20%;" required>
</center>
</div>
<br>
<div style="max-width: 470px;">
<center><input type="password" name="password"
placeholder="password" style="margin-left: 20%;"></center>
</div>
<br>
<div style="max-width: 470px;">
<center><button style = "border:0px; background-color:#4285F4;
margin-top:8%; height:35px; width:80%;margin-left:19%;" type =
"submit" value = "Login" >
<strong>Login</strong>
</button></center>
</div>
</form>
</body>
</html>
My loggedin.html is :
{% extends 'base.html' %}
<html>
<head>
<title>{% block title%}{{ username }}{% endblock %}</title>
</head>
<body>
{% block content %}
You are : <strong>{{ username }}</strong>
{% endblock %}
When i am running the code and then entering the name and password in the dield input at /connection/ url, it is redirecting to /connectionlogin/ url but showing valid for all the usernames i am entering in the forms rather it should show only those names which are stored in the database name Dreamreal.
Somebody please help!
You are validating the username field, so you should name your method clean_username. Django will only call the clean_message field if the form has a field called message.
To see any form errors in the template you need to include the form in the context when you call render:
return render(request, 'loggedin.html', {'username' : username, 'form': MyLoginForm}
And you won't see the errors in the template unless you use form in the template. The easiest way to do this is to include {{ form }}. If you need to do something more advanced, see the docs on working with forms.