I am getting the following error:
Cannot assign "<django.db.models.fields.related.ForeignKey>": "Worry.user" must be a "User" instance.
I trying to assign the id of the current user to an object I have just created.
This is part of my models.py:
from django.contrib.auth.models import User
from django.forms import ModelForm
from django.db import models
class UserForm (ModelForm) :
class Meta:
model = User
class Worry(models.Model) :
user = models.ForeignKey(User) #Many worries to 1 user relation
This is part of my views.py:
from django.db import models
from django.shortcuts import render_to_response, redirect, get_object_or_404
from django.template import RequestContext
from django.contrib.auth.models import User
from holaProy.models import UserForm, Worry, WorryForm, Statistics, StatisticsForm
def worry_add (request):
form = WorryForm (request.POST or None)
if form.is_valid():
wform.user = models.ForeignKey('User') #HERE IS THE PROBLEM I THINK
wform.save()
return redirect (index)
return render_to_response ('holaProy/worry_add.html', {'worry_form': form}, context_instance = RequestContext(request))</code>
How should I do it in order to succesfully assign the current user id to the "user" field for the actual worry instance?
The issue is, indeed, on that line:
wform.user = models.ForeignKey('User')
wform.user should be set to a User instance. Something like this:
user = request.user # Retrieve proper user according to your needs
wform.user = user
Try:
def worry_add(request):
form = WorryForm(request.POST or None)
if request.method == 'POST' and form.is_valid():
worry = form.save(commit=False)
worry.user = #assign this to an instance of a User object
worry.save()
That's the line where you are having your problem.
Basically, you are searching for a string. You need to get the actual database object before.
Try this:
User = User.objects.get(pk='User')
wform.user = models.ForeignKey('User') #Now User refers to the database object, not a string
Related
I want to create a record in the register model immediately after creating user
But unfortunately, an error
'function' object has no attribute 'objects'
shows me
views.py code:
from django.shortcuts import render,redirect
from .forms import userregister
from django.contrib.auth.models import User
from testapp.models import register
def register(request):
if request.method == 'POST':
form = userregister(request.POST)
if form.is_valid():
cd = form.cleaned_data
User.objects.create_user(cd['username'],cd['email'],cd['password'])
register.objects.create(address='NONE' , phone = 'NONE' ,username_id= cd['id'])
return redirect('testapp:index')
else:
form = userregister()
context = {'form' : form}
return render(request,'register.html',context)
models.py code
from django.db import models
from django.contrib.auth.models import User
class register(models.Model):
address = models.CharField(max_length=200)
phone = models.CharField(max_length=11)
username = models.OneToOneField(User,on_delete = models.CASCADE)
def __str__ (self):
return str(self.username)
I want to create a record in the register model immediately after the user is added, with the value NONE and the foreign key should be the same user as the one created now.
It is not a good practice to name same your model and view name so kindly change model name to Register as it is written in PascalCase and the view name can be remain same or change to register_view.
I know there are a lot of solutions for this problem but they seem a bit different than mine. Here is my models.py:
from __future__ import unicode_literals
from django.db import models
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.postgres.fields import HStoreField
# Create your models here.
class Events(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
name = models.CharField(max_length=32)
start = models.CharField(max_length=32)
end = models.CharField(max_length=32)
Very simple table and I want the primary key in Auth_user to be the foreign key in my Events table. So of course this would mean that a User has to be logged in and authenticated for this to work. In my views.py I have:
def createEvent(request):
if request.method == "POST":
user = request.user
print (user) # Check for Authentication
name = request.POST['name']
start = request.POST['start']
end = request.POST['end']
Events.objects.create(
name = name,
start = start,
end =end,
)
The print statement will print out the current user logged in. I can confirm that this part does show that a user is logged in and that this user is in the auth_user table with a unique id. However, when I try to submit a form, I get a null value for the user column. Any ideas?
Making what you have right now work:
def createEvent(request):
if request.method == "POST":
user = request.user
print (user) # Check for Authentication
name = request.POST['name']
start = request.POST['start']
end = request.POST['end']
# The user has to be included before being saved
Events.objects.create(name=name, start=start, end=end, user=user)
Some better practices:
Using a ModelForm (note there are class based generic views that make this easier too), and the login_required decorator
# forms.py
from django.forms import ModelForm
from .models import Event
class EventForm(ModelForm):
class Meta:
model = Event
fields = ('user', 'start', 'end', 'name')
# views.py
from django.contrib.auth.decorators import login_required
#login_required
def create_event(request):
if request.POST:
form = EventForm(request.POST)
if form.is_valid():
form.save()
else:
form = EventForm()
return render(..., {'form': form})
Just add the user instance because it's required by Events. I think you should use DateField or DateTimeField on start and end field. Not sure but I think you plan to put a date value there.
Events.objects.create(user=request.user, name=name, start=start, end=end)
You should also add a #login_required for your function.
My solution is this:
from django.contrib.auth.models import User
user = request.user
user_id = User.objects.get(username=user).pk
name = request.POST['name']
start = request.POST['start']
end = request.POST['end']
Events.objects.create(
user_id=user_id,
name = name,
start = start,
end =end,
)
Is that an alright solution? Could there be something better?
So I've been trying my hand at Django authentication. I tried to create a register view which implements two models the django.contrib.auth.models.User and one custom model which shares a OneToOne relationship with User.
Here's the relevant code
models.py
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
# Create your models here.
class UserProfile(models.Model):
user = models.OneToOneField(User)
SapID = models.IntegerField(default=60000000000)
def __str__(self):
return self.user.username
views.py
from django.shortcuts import render
from .forms import UserFormRegister, UserForm
# Create your views here.
def register(request):
if request.method == 'POST':
user_form = UserForm(data = request.POST)
users_form = UserFormRegister(data = request.POST)
if user_form.is_valid() and users_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
userregister = users_form.save()
userregister.user = user
userregister.save()
return redirect('/#/')
else:
user_form = UserForm()
users_form = UserFormRegister()
return render(request, 'register.html',{'user_form':user_form, 'users_form':users_form},)
forms.py
from django import forms
from django.contrib.auth.models import User
from .models import UserProfile
class UserForm(forms.ModelForm):
password = forms.CharField(widget = forms.PasswordInput())
class Meta:
model = User
fields=('username','password','email','first_name','last_name',)
class UserFormRegister(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('SapID', )
SapID is a unique id that each user will have.
Now,when I try to register, the user object gets created but the user profile object doesnt. I get an error saying "NOT NULL constraint failed: foo_userprofile.user_id". What am I missing?
The issue, is when you do users_form.save(), it actually tries to create at object, and save it to the database where the constraint raises exception. To avoid this, you can use the commit=False argument which creates the profile object in memory, but does not save it to the database just yet.
userregister = users_form.save(commit=False)
userregister.user = user
userregister.save()
More on commit=False:
This save() method accepts an optional commit keyword argument, which
accepts either True or False. If you call save() with commit=False,
then it will return an object that hasn’t yet been saved to the
database. In this case, it’s up to you to call save() on the resulting
model instance. This is useful if you want to do custom processing on
the object before saving it, or if you want to use one of the
specialized model saving options. commit is True by default.
I have extended the Django User model as per the docs: https://docs.djangoproject.com/en/1.8/topics/auth/customizing/
models.py:
from django.db import models
from django.contrib.auth.models import User
class Onboarding(models.Model):
user = models.OneToOneField(User)
onboarding_status = models.SmallIntegerField(max_length=1, default=1)
views.py:
from django.shortcuts import render
from django.contrib.auth.models import User
from .models import Onboarding
def home(request):
current_user = request.user
u = User.objects.get(id=current_user.id)
onboarding_status = u.onboarding.onboarding_status
context = {
}
if onboarding_status == 1:
return render(request, "onboarding/step_1.html", context)
else:
return render(request, "onboarding/step_2.html", context)
However, I get an error RelatedObjectDoesNotExist at /onboarding/. User has no onboarding.
How do I accurately reference the onboarding_status integer I have associated with the user from a view?
Firstly, it is pointless to query User for the request.user ID. request.user is already a User: the value of u is exactly the same as the current_user value you started with.
Secondly, the error is telling you that this particular User has no related Onboarding instance. You need to create one, probably when you create the user.
You have assigned onboarding_status = u.onboarding.onboarding_status but your context = {} is empty. Try context={'onboarding_status': onboarding_status}. And then in the template files, that is step_1.html or step_2.html, use {{ onboarding_status }} to call the variable.
I want to save the email and name fields in django default table called UserSignup
my models.py is:
from django.db import models
class UserSignup(models.Model):
mailid = models.CharField(max_length=100)
name = models.CharField(max_length=100)
my views.py is:
from django import views
from django.shortcuts import render_to_response
from django.template import RequestContext
from Deals.signup.forms import signup
from django.contrib.auth.models import User
from django.http import HttpResponse
def usersignup(request,form_class=signup):
form = form_class()
print form
if form.is_valid():
mail= UserSignup(mailid=request.POST['mailid'])
mail.save()
name= UserSignup(name=request.POST['name'])
name.save()
else:
form = form_class()
return render_to_response('signup/registration_form.html',{'form':form})
and forms.py is
from django import forms
from django.contrib.auth.models import User
from Deals.signup.models import *
from django.utils.translation import ugettext_lazy as _
class signup(forms.Form):
email = forms.EmailField(widget=forms.TextInput(),
label=_("Email address:"))
username = forms.RegexField(regex=r'^\w+$',
max_length=30,
widget=forms.TextInput(),
label=_("Name:"))
def save(self,request,update):
name = self.cleaned_data['name']
name.save()
email = self.cleaned_data['email']
email.save()
Please help me in saving my forms input in database
Check the Django documentation properly http://docs.djangoproject.com/en/dev/topics/forms/
Just change your code in views.py.
def usersignup(request,form_class=signup):
if request.method == 'POST': #If its a form submission, the method is POST
form = form_class(request.POST)
if form.is_valid():
newuser = form.save()
else: #Else display the form
form = form_class()
return render_to_response('signup/registration_form.html',{'form':form})
The 'save' function in your forms file is incorrect and is not needed.
On a side note, your "UserSignup" is not a default User Table. That would be the user model provided by Django. And that already has the fields that you are creating in UserSignup. Why don't you use that feature of Django?
It might be better to save the model elements in the form in one time.
def save(self):
new_user = User.objects.create_user(name = self.cleaned_data['name'],
email = self.cleaned_data['email'])
return new_user