I am working on an app with Django backend and I am currently developing the signup page. Here's my code:
models.py
from django.db import models
from django.contrib.auth.models import User
from django.core.validators import MaxValueValidator, MinValueValidator
from datetime import date
from .countries import COUNTRIES
from .hobbies import HOBBIES
class Hobbies(models.Model):
hobby = models.CharField(max_length=255, choices=HOBBIES)
class Profile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
def username(self):
usern = User.objects.get(id=self.user.id)
usern = usern.username
return usern
setup = models.BooleanField(default=False)
gender = models.CharField(max_length=100, blank=True)
dob = models.DateField(blank=True)
def age(self):
today = date.today()
age = today.year - self.dob.year - ((today.month, today.day) < (self.dob.month, self.dob.day))
return age
orgin = models.CharField(max_length=300, choices=COUNTRIES, blank=True)
lives = models.CharField(max_length=300, choices=COUNTRIES, blank=True)
bio = models.CharField(max_length=150, blank=True)
email = models.CharField(max_length=255, blank=True)
image = models.ImageField(upload_to='images', blank=True)
hobbie = models.ManyToManyField('Hobbies', blank=True)
views.py-
from django.shortcuts import render
from rest_framework import viewsets, status
from .serializers import UserSerializer, ProfileSerializer
from .models import Profile
from django.db import IntegrityError
from rest_framework.response import Response
from rest_framework.decorators import action
from django.contrib.auth.models import User
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.permissions import IsAuthenticatedOrReadOnly, BasePermission
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json
from django.contrib.auth import authenticate
# Create your views here.
#.....
#csrf_exempt
def signup(request):
if request.method == 'POST':
data = json.loads(request.body)
username = data.get("username", "")
password = data.get("password", "")
try:
user = User.objects.create_user(username, '',password)
user.save()
created = True
profile = Profile.objects.create(user=user)
profile.save()
except IntegrityError:
created = False
return JsonResponse(created, safe=False)
Everything works when I try to create a new user without creating a new profile. But when I try to create a Profile when I am creating the User I get an "IntegrityError.": "NOT NULL constraint failed: home_profile.dob" .How can I fix this?
Your problem lies here:
dob = models.DateField(blank=True)
DateFields, if empty, are rendered as null in the database, so you need to add
dob = models.DateField(blank=True, null=True)
As a rule of thumb, blank=True says the field need not be filled in for forms. null=True says the database can accept a null value. The exception is for string types, eg CharField and TextField, which only use blank=True as django saves an empty string, "", rather than a null value.
Related
In the following code I created a Login API but when I hit the request in Postman it's always give me error response. How to rectify the problem?
This is my views.py file
from django.shortcuts import render
from rest_framework.permissions import AllowAny
from rest_framework.views import APIView
from rest_framework.response import Response
from .serializers import UserSerializer, RegisterSerializer, UserLoginSerializer
from django.contrib.auth.models import User
from rest_framework import generics, permissions
from rest_framework import status
from django.contrib.auth import authenticate,login
from django.contrib import auth
# from knox.models import AuthToken
# Create your views here.
from django.views.decorators.csrf import csrf_exempt
from rest_framework.decorators import api_view
#Login Credentials
"//Create a Login API in Django?"
class UserLoginView(APIView):
permission_classes = (AllowAny,)
serializer_class = UserLoginSerializer
def get(self,request,format=None):
serializer=UserLoginSerializer(data=request.data)
# print(serializer.is_valid(raise_exception=True));
if serializer.is_valid(raise_exception=True):
email = serializer.data.get('email')
password = serializer.data.get('password')
print(email)
print(password)
user=authenticate(email=email,password=password)
print(user)
if user is not None:
login(request, user)
return Response({'msg':'Login Success'},status=status.HTTP_200_OK)
else:
return Response({'msg':{'Email or Password Does not match'}},status=status.HTTP_404_NOT_FOUND)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#This is my serializer.py file.
class UserLoginSerializer(serializers.ModelSerializer):
email=serializers.EmailField(max_length=200)
class Meta:
model = User
fields= ['email','password']
When I hit the request then its always give me error
Django default User model takes the (username & password) field for Authentication.
in your code, you tried to authenticate with (email & password) so it gives None on every login request.
try for Authentication (username & password) instead of (email & password) I mean change like this...
user=authenticate(username=username,password=password)
Instead of...
user=authenticate(email=email,password=password)
If you still want to Authenticate with email then you need to Customize the Default User model
for Customizing Django User Model refer to the link here
User Model Cutomizaion code is here...
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from .managers import CustomUserManager
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), unique=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(default=timezone.now)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserManager()
def __str__(self):
return self.email
In the above code this line USERNAME_FIELD = 'email' give permission to authenticate with Email field Insted of Username field
I created a Django API to create a new user. However, when I try to create a user I get the error message:
IntegrityError at /api/v1/users/register/ NOT NULL constraint failed: accounts_user.user_id
This is what I have in models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class User(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=100, blank=True)
location = models.CharField(max_length=100, blank=True)
password = models.CharField(max_length=32)
email = models.EmailField(max_length=150)
signup_confirmation = models.BooleanField(default=False)
def __str__(self):
return self.user.username
#receiver(post_save, sender=User)
def update_profile_signal(sender, instance, created, **kwargs):
if created:
User.objects.create(user=instance)
instance.profile.save()
In serializers.py
from rest_framework import serializers
from .models import User
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('user_id', 'name', 'location', 'password', 'email', 'signup_confirmation')
and my views.py
from rest_framework import viewsets
from .serializers import UserSerializer
from .models import User
from rest_framework.decorators import action
from .forms import SignUpForm
from .tokens import account_activation_token
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all().order_by('name')
serializer_class = UserSerializer
#action (detail=True, methods=['post'])
def register(self, request):
print(request)
Any ideas on what I can do to resolve this error
As John wrote in a comment:
Here you have a problem: fields = ('user_id',...).
I also advise you to change your User model. If you don't need separating (I suppose you don't), it is way better to create your User with inheritance directly from AbstractUser instead of creating in fact doubled User models.
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
...
In this way you will already have username, password and email, but you can add anything else in same model, instead of using user.user etc.
I'm building a blog on Django and know i have to make a personal page for see all the posts published by the user we're logged in now.
I'm using some querysets so.
Her my code
my models.py
from django.db import models
from django.conf import settings
from django.utils import timezone
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
Here my forms.py
from django.contrib.auth.forms import UserCreationForm
from django import forms
from django.contrib.auth.models import User
from .models import Post
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['username','email','password1','password2','user_permissions','is_staff','date_joined']
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'text', 'author']
And that's the view which is gonna filter the posts in base of the logged user
from django.contrib.auth.models import User
from django.contrib import messages
from django.contrib.auth import authenticate,login,logout
from django.contrib.auth.decorators import login_required
from django.utils import timezone
from .forms import CreateUserForm
from .models import Post
from .forms import PostForm
def user_data(request, pk):
user_data = User.objects.get(pk=pk)
posts = user_data.post_set.filter(author=user_data)
context = {'user_data':user_data, 'posts':posts}
return render(request, 'account/user_data.html', context)
#So it returns me just the user data like name, email or date_joined but not his posts
This should give you posts of logged in users from your view
def user_data(request, pk):
posts=Post.objects.filter(author=request.user)
context = {'posts':posts}
return render(request, 'account/user_data.html', context)
I’m trying to get the username of the current logged in user using OneToOneField to populate in the admin once the user submits a form.
The username should go in the user column of admin.py.
I’ve tried various methods and still no luck. I’m new to this and this is my first Django application I’m building so I’m not sure what I’m missing.
I’m stuck and have no idea what I’m doing so any help is gladly appreciated.
Can someone please help? What am I missing?
Thanks!
Code Below:
user_profile/models
from django.db import models
from django.urls import reverse
from django.contrib.auth.models import AbstractUser, UserManager
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings
from users.forms import CustomUserCreationForm, CustomUserChangeForm
from users.models import CustomUser
class Listing (models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
name = models.CharField(max_length=100)
address = models.CharField(max_length=100)
zip_code = models.CharField(max_length=100)
mobile_number = models.CharField(max_length=100)
cc_number = models.CharField(max_length=100)
cc_expiration = models.CharField(max_length=100)
cc_cvv = models.CharField(max_length=100)
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = Listing.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
user_profile/admin.py
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from user_profile.forms import HomeForm
from user_profile.models import Listing
# Register models here.
class UserProfileAdmin(admin.ModelAdmin):
list_display = ['name', 'address', 'zip_code', 'mobile_number', 'created', 'updated', 'user']
list_filter = ['name', 'zip_code', 'created', 'updated', 'user']
admin.site.register(Listing, UserProfileAdmin)
#admin.site.unregister(Listing)
master_application/settings.py
AUTH_USER_MODEL = 'users.CustomUser'
AUTH_PROFILE_MODULE = 'users.UserProfile'
users/models.py
from django.contrib.auth.models import AbstractUser, UserManager
from django.contrib.auth.models import User
from django.db import models
from django.urls import reverse
class CustomUserManager(UserManager):
def get_by_natural_key(self, username):
case_insensitive_username_field = '{}__iexact'.format(self.model.USERNAME_FIELD)
return self.get(**{case_insensitive_username_field: username})
class CustomUser(AbstractUser):
objects = CustomUserManager()`
Your signal is broken; kwargs will never have a user key so the profile will never be created. What you actually want to do is to check that the signal is being called on creation (rather than on update), add then create an instance of Listing:
if kwargs['created']:
user_profile = Listing.objects.create(user=kwargs['instance'])
Note, the AUTH_PROFILE_MODULE setting has not been used for years, you should remove it.
Using the Stripe API to create a credit card checkout form on my website.
I am trying to test the following line in my view.py of the app checkout.
print (request.user.userStripe.stripe_id)
It could be the way my Users is set up.. I tried importing the models from the user app. I just don't understand why it can't see it.
I have two apps: users and checkout
I am the following error in the debug page
AttributeError at /checkout/
'User' object has no attribute 'userStripe'
Request Method: GET
Request URL: http://127.0.0.1:8000/checkout/
Django Version: 1.11
Exception Type: AttributeError
Exception Value:
'User' object has no attribute 'userStripe'
Exception Location: /home/dominic/Desktop/Projects/decentraland/website/manaland/manaland/env/lib/python3.4/site-packages/django/utils/functional.py in inner, line 239
Python Executable: /home/dominic/Desktop/Projects/decentraland/website/manaland/manaland/env/bin/python
Python Version: 3.4.3
Python Path:
['/home/dominic/Desktop/Projects/decentraland/website/manaland/manaland',
'/home/dominic/Desktop/Projects/decentraland/website/manaland/manaland/env/lib/python3.4',
'/home/dominic/Desktop/Projects/decentraland/website/manaland/manaland/env/lib/python3.4/plat-x86_64-linux-gnu',
'/home/dominic/Desktop/Projects/decentraland/website/manaland/manaland/env/lib/python3.4/lib-dynload',
'/usr/lib/python3.4',
'/usr/lib/python3.4/plat-x86_64-linux-gnu',
'/home/dominic/Desktop/Projects/decentraland/website/manaland/manaland/env/lib/python3.4/site-packages']
Server time: Mon, 2 Jul 2018 22:38:35 +0000
checkout.views.py
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from users.models import User, profile, userStripe
from django.views import generic
from django.views.generic import CreateView
#TODO UPDATE WITH LIVE VERISON FOR STRIPE API KEYS
import stripe
stripe.api_key = settings.STRIPE_SECRET_KEY
# Create your views here.
#login_required
def checkout(request):
publishKey = settings.STRIPE_PUBLISHABLE_KEY
print (request.user.userStripe.stripe_id)
if request.method == 'POST':
token = request.POST['stripeToken']
# Token is created using Checkout or Elements!
# Get the payment token ID submitted by the form:
try:
charge = stripe.Charge.create(
amount=999,
currency='usd',
description='Example charge',
source=token,
)
except stripe.error.CardError as e:
pass
context = {'publishKey': publishKey}
template = 'checkout/checkout.html'
return render(request, template, context)
users.models.py
from django.contrib.auth.models import AbstractUser
from django.core.urlresolvers import reverse
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from allauth.account.signals import user_logged_in, user_signed_up
import stripe
stripe.api_key = settings.STRIPE_SECRET_KEY
#python_2_unicode_compatible
class User(AbstractUser):
# First Name and Last Name do not cover name patterns
# around the globe.
name = models.CharField(_('Name of User'), blank=True, max_length=255)
bio = models.CharField( blank=True, max_length=255)
image = models.ImageField(null=True, blank=True)
def __str__(self):
return self.username
def get_absolute_url(self):
return reverse('users:detail', kwargs={'username': self.username})
class profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
description = models.CharField( blank=True, max_length=255)
image = models.ImageField(null=True, blank=True)
def __str__(self):
return self.user.username
class userStripe(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
stripe_id = models.CharField(max_length=200, null=True, blank=True)
def __unicode__(self):
if self.stripe_id:
return str(self.stripe_id)
else:
return self.user.username
def stripeCallback(sender, request, user, **kwargs):
user_stripe_account, created = userStripe.objects.get_or_create(user=user)
if created:
print ('created for %s'%(user.username))
if user_stripe_account.stripe_id is None or user_stripe_account.stripe_id == '':
new_stripe_id = stripe.Customer.create(email=user.email)
user_stripe_account.stripe_id = new_stripe_id['id']
user_stripe_account.save()
def profileCallback(sender, request, user, **kwargs):
userProfile, is_created = profile.objects.get_or_create(user=user)
if is_created:
userProfile.name = user.username
userProfile.save()
user_logged_in.connect(stripeCallback)
user_signed_up.connect(profileCallback)
user_signed_up.connect(stripeCallback)
You should use lowercase model name, print(request.user.userstripe.stripe_id).
Better set related_name in your OneToOneField so you will know exactly how to access userStripe from user.
class userStripe(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='user_stripe')
...
print(request.user.user_stripe.stripe_id)
Use request.user.userStripe.stripe_id.
You are using request.User. Instead you have to use: request.user.
you miss typing userStripe in print (request.user.userStripe.stripe_id)
try write userstripe :
print (request.user.userstripe.stripe_id)
it worked for me very nice