null value in column "user_id" violates not-null constraint Django - python

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?

Related

How do I add username of logged in user to model field in django

How to add username of currently logged in user to field in my model? For example, I need to store info about user like name, email and so on in model, other than default Django user model, but I still use default one to store credentials. I want to establish relationship between those, so I created username field in my model. How do I fill it with current user's username upon saving the corresponding form?
My model
class ApplicantProfile(models.Model):
name = models.CharField(max_length = 50)
dob = models.DateField()
email = models.EmailField()
description = models.TextField()
username = <something>
What do I change <something> with?
My form
class ApplicantProfileEdit(forms.ModelForm):
class Meta:
model = ApplicantProfile
fields = [
'name',
'dob',
'email',
'description',
]
My view
def ApplEditView(request):
form = ApplicantProfileEdit(request.POST or None)
if form.is_valid():
form.save()
form = ApplicantProfileEdit()
context = {
'form':form
}
return render(request, "applProfileEdit.html", context)
P.S. I tried to import models straight to my views.py, and assign request.user.username to username field of the model in my view, but it didn't work, just left that field empty. I had username as CharField when I tried this.
It is not a good idea to save the username itself, or at least not without a FOREIGN KEY constraint. If later a user changes their name, then the username now points to a non-existing user, if later another user for example changes their username to thatusername, then your ApplicantProfile will point to the wrong user.
Normally one uses a ForeignKey field [Django-doc], or in case each ApplicantProfile points to a different user, a OneToOneField [Django-doc]:
from django.conf import settings
from django.db import models
class ApplicantProfile(models.Model):
name = models.CharField(max_length = 50)
dob = models.DateField()
email = models.EmailField()
description = models.TextField()
# maybe a OneToOneField
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
In the view:
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect
#login_required
def appl_edit_view(request):
if request.method == 'POST':
form = ApplicantProfileEdit(request.POST)
if form.is_valid():
form.instance.user = request.user
form.save()
return redirect('some-view-name')
else:
form = ApplicantProfileEdit()
context = {
'form':form
}
return render(request, 'applProfileEdit.html', context)
Note: In case of a successful POST request, you should make a redirect
[Django-doc]
to implement the Post/Redirect/Get pattern [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.
Note: You can limit views to a view to authenticated users with the
#login_required decorator [Django-doc].

How to get information from one Django models object?

today I'm trying to get and print all my users emails, who had chose selection "Value1".
This is how my model.py looks like:
from django.db import models
class Vartotojas(models.Model):
email = models.EmailField()
option = models.CharField(max_length=30)
Forms.py :
from django import forms
from emailai.models import Vartotojas
class VartotojasForm(forms.Form):
email = forms.EmailField(max_length=100)
my_field = forms.MultipleChoiceField(choices=(('Value1','Value1'),('Value2','Value2')), widget=forms.CheckboxSelectMultiple())
def save(self):
mymodel = Vartotojas(
email=self.cleaned_data['email'],
option=self.cleaned_data['my_field'],
)
mymodel.save()
And finally my views.py "
from django.shortcuts import render
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from emailai.models import Vartotojas
from renginiai.forms import VartotojasForm
def name(request):
if request.method == 'POST':
form = VartotojasForm(request.POST)
if form.is_valid():
a = Vartotojas.objects.filter(option="u'Value1'") # How to do it right?
# Now How To Get those object emails?
new_user = form.save()
return render(request, "Vartotojas-result.html", {
'form': form, #BLABLABLA,
})
else:
form = VartotojasForm()
return render(request, "Vartotojas-form.html", {
'form': form,
})
I commented my questions inside my views.py. I hope you will be able to help me. Thank you in advance!
I re-write my code with getlist. Now it looks like this:
views.py :
if form.is_valid():
email = form.cleaned_data['email']
option = request.POST.getlist('my_field')
new_user = form.save(email, option)
forms.py:
email = forms.EmailField(max_length=100)
my_field = forms.MultipleChoiceField(choices=(('Value1','Value1'),('Value2','Value2')), widget=forms.CheckboxSelectMultiple())
def save(self, email, option):
mymodel = Vartotojas(
email=email,
option = option,
)
mymodel.save()
As you see I pasted just most important places. By the way, users can choose 2 values, that's why I use checkbox. But still it not working.
I believe you want to use the values_list property like so:
Vartotojas.objects.filter(option=u"Value1").values_list("email", flat=True)
to get a list of all email addresses. You may also want to apply a distinct() to that if you're not already preventing duplicates. On a side note, look into ModelForms: it looks like that would save you a fair bit of the time/ code you have written for dealing with this. You could create a ModelForm based on your Vartotojas object and not have to write the explicit save() method you have.

custome user creation in django fields not storing value

I am trying to make a user registration form in django.
I browsed through many links but I am still confused. I am making some sill mistake please point it out.
here is my code:
models.py
from django.db import models
from django.db.models.signals import post_save
from django.contrib.auth.models import User
class UserProfile(models.Model):
mobile = models.CharField(max_length = 20, null=False)
address = models.CharField(max_length = 200)
user = models.OneToOneField(User, unique=True)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class CustomerRegistrationForm(UserCreationForm):
mobile = forms.CharField(max_length = 20)
address = forms.CharField(max_length = 200)
class Meta:
model = User
fields = ('username','email','mobile','address','password1','password2')
view.py
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.template import RequestContext
from django.core.context_processors import csrf
from neededform.forms import CustomerRegistrationForm
def register(request):
print "I am in register function"
if request.method == 'POST':
if request.method == 'POST':
form = CustomerRegistrationForm(request.POST)
if form.is_valid():
f = form.save()
return HttpResponseRedirect('/registered/')
else:
args = {}
args.update(csrf(request))
args['form'] = CustomerRegistrationForm()
return render_to_response('User_Registration.html', args ,context_instance = RequestContext(request))
what I am thinking is that when I do a form.save() in views.py, django should create the user in auth_user table and must insert the values (i.e mobile and address ) in the UserProfile table also.
but what happening is that it is inserting data in auth_user table correctly but in the UserProfile table only id and user_id coloumns are filled, mobile and address both remains empty.
What am I doing wrong ? What else must be done ?
Thank you.
Take a look at the following:
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
You create a UserProfile object which only has its user attribute set!
I don't think that using signal is the best approach to your problem since it's not easy to pass the mobile and address from your form to the Profile creation point. Instead you can override the save() method of your CustomerRegistrationForm where you'd first save the user and then create the profile. Something like this:
class CustomerRegistrationForm(UserCreationForm):
# rest code ommited
def save(self, commit=True):
user = super(CustomerRegistrationForm, self).save()
p = UserProfile.objects.get_or_create(user=user )
p[0].mobile = self.cleaned_data['mobile']
p[0].address = self.cleaned_data['address']
p[0].save()
return user

Can't assign a value (user id) to a ForeignKey field

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

How to save the email and name fields in the Django deafult User table

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

Categories