How to get information from one Django models object? - python

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.

Related

Django Modelform doesn't accept selection on POST

The dropdown list appears correctly in the html, However I am unable to figure out why I run into the same error time after time when I try to submit / .
"Select a valid choice. That choice is not one of the available choices."
the problem context
I have two models defined in Django. One CourseModel database to hold all the offered courses and one registration database to link a course to a user.
models.py
from django.db import models
# Create your models here.
class CourseModel(models.Model):
course = models.CharField(max_length=100)
date = models.DateField(max_length=100)
time = models.TimeField()
location = models.CharField(max_length=100)
datetime = models.DateTimeField()
class RegistrationModel(models.Model):
name = models.CharField(max_length=100)
adress = models.CharField(max_length=100)
city = models.CharField(max_length=100)
email = models.EmailField(max_length=100)
course = models.ForeignKey('self', on_delete=models.CASCADE)
def __str__(self):
return self.name
I use modelForm to create a registration form, where the user can subscribe for a course from a dropdown list.
forms.py
from django.forms import ModelForm, RegexField
from home.models import RegistrationModel, CourseModel
from django import forms
import datetime
class RegistrationForm(ModelForm):
def __init__(self, *args, **kwargs):
super(RegistrationForm, self).__init__(*args, **kwargs)
self.fields['course'].queryset = CourseModel.objects.exclude(date__lt=datetime.datetime.today()).values_list('datetime', flat=True)
self.fields['course'].empty_label = None
class Meta:
model = RegistrationModel
fields = '__all__'
views.py
from django.shortcuts import render, redirect
from home.forms import RegistrationForm
from .models import CourseModel
import datetime
def home(request):
return render(request, 'home/home.html')
def registration(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
crs = request.POST.get('course')
print(crs)
if form.is_valid():
cleanform = form.save(commit=False)
cleanform.course = crs
cleanform.save()
return redirect('home')
else:
form = RegistrationForm()
return render(request, 'home/registration.html', {'form': form})
In the RegistrationForm's __init__() method, your self.fields['course'].queryset = ...values_list('datetime', flat=True) returns datetime instances. See values_list() docs.
I believe this may cause the issue. I guess the queryset should return CourseModel instances, based on the Django docs:
ForeignKey is represented by django.forms.ModelChoiceField, which is a ChoiceField whose choices are a model QuerySet.
Also, your RegistrationModel.course field has a foreign key to 'self' instead of the CourseModel. Not sure if that is what you want.
Other examples of setting the field queryset can be found here.

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

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?

How to update password in django?

I want to edit my user data from template, bellow are my codes.
def guru_edit(request, id):
Guru = get_object_or_404(DataGuru, GuruUser_FK_id=id)
GuruUser = get_object_or_404(User, id=id)
if request.method == 'POST':
form_guru = dataguruform(request.POST, instance=Guru)
form_user = userform(request.POST, instance=GuruUser)
if form_guru.is_valid() and form_user.is_valid():
form_guru.save()
form_user.save()
return redirect('index_guru')
else:
form_guru = dataguruform(instance=Guru)
form_user = userform(instance=GuruUser)
return render(request, 'guru/guru_tambah.html', {'form_user': form_user,'form_guru':form_guru})
this is my forms.py
class userform(ModelForm):
class Meta:
model = User
fields = ('username','email', 'password','is_staff','is_active','is_superuser')
widgets={
'password':TextInput(attrs={'type':'password'})
}
But when i was save from template, the password is not encrypted like it used to be, but just plaintext.
How to make it encripted?
Do not set the password via a form field. Set the password with User.set_password() method which accepts your unencrypted password:
user_form = UserForm(request.POST, instance=user)
if user_form.is_valid():
user = user_form.save()
user.set_password('unencrypted_password') # replace with your real password
user.save()
return redirect('index_guru')
I have named the variables and forms in a bit more Django-ish way here, as you can see.
Background: The password in Django is stored as a (most commonly PBKDF2) hash in your database. set_password takes care of seeking the correct hashing method and salting and hashing your passwords correctly.
Forms should merely contain something like password and password_check fields that are used to check if your user inputs his or her password correctly. They should not be used to save a plain password into your database, which I suspect is happening here by default.
You can use set_password inside your forms as well by overriding the UserForm.save() method.
Take the time to read through this document:
https://docs.djangoproject.com/en/dev/topics/auth/passwords/
Just create a view using Django's built in forms and views:
In your views.py:
from django.contrib.auth.views import PasswordChangeView
from django.contrib.auth.forms import PasswordChangeForm
class UpdatePassword(PasswordChangeView):
form_class = PasswordChangeForm
success_url = '/user/edit-profile'
template_name = 'app/change-password.html'
Inside your urls.py:
from . import views
urlpatterns = [
path('/change-password', views.UpdatePassword.as_view(), name="update_password"),
]

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

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