Django: model.save() is not saving, but no error msg - django

Hi Stackoverflow people,
I am trying to write my own contact form in Django, where users can write messages to me and the message will be emailed and saved in the DB for tracking.
But somehow, the model.save() won't save anything. When I check the entries with Admin, the Contact table is empty. I also do not get any error messages.
The sending of the message hasn't been fully implemented yet.
To test the code, I set up some status messages in the if/else branch, but I do not get any of the statement - so the code seems to be neglected. But I do not understand why? Any suggestions?
I am not sure if I hand over the request variable between the views.py and forms.py correctly. Could this be the issue?
Thank you for your suggestions.
models.py
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.mail import send_mail
import datetime, random
class Contact(models.Model):
"""
Contact class is the model for user messages.
Every message will be sent.
"""
CATEGORIES = (
('Suggestion', 'I have a suggestion'),
('Feedback', 'General feedback'),
('Complaint', 'You should improve ...'),
# ('', ''),
)
category = models.CharField(_('Message Category'),
max_length=10,
choices=CATEGORIES)
subject = models.CharField(_('Message Subject'),
max_length=255,)
sender = models.EmailField(_('Email Address'),)
message = models.TextField(_('Message Box'),)
# date and ansbwered are not visible to the user
timeOfMessage = models.DateTimeField(_('Time of sending'), blank=True, null=True)
answered = models.BooleanField(_('Answered?'),
default=False,)
def __unicode__(self):
return '%s' % self.sender
def send_and_save(self):
subject_new = ':'.join(self.category, self.subject)
send_mail(subject_new,
message,
sender,
'info#future_domain_address.com')
return True
forms.py
from django.forms import ModelForm
from django.utils.translation import ugettext_lazy as _
from contact.models import Contact
import datetime
class ContactForm(ModelForm):
class Meta:
model = Contact
exclude = ('answered', 'timeOfMessage')
def save_and_email(request):
if request.method == 'POST':
form = self(request.POST)
if form.is_valid():
# contact.cleaned_data()
contact = form.save(commit=False)
contact.timeOfMessage = datetime.now()
contact.answered = False
contact.save()
print "was here"
return True
else:
print "Saving Failed"
else:
print "POST failed"
return False
views.py
from django.views.generic.simple import direct_to_template
from django.shortcuts import redirect, get_object_or_404, render_to_response
from django.utils.translation import ugettext as _
from django.http import HttpResponseForbidden, Http404, HttpResponseRedirect, HttpResponse
from django.template import RequestContext
from django.core.mail import BadHeaderError
from contact.forms import ContactForm
def contact(request):
if request.method == 'POST':
try:
contactform = ContactForm()
contactform.save_and_email
except BadHeaderError:
return HttpResponse(_('Invalid header found.'))
return HttpResponseRedirect('/contact/thankyou/')
return render_to_response('contact/contact.html', {'form': ContactForm()},
RequestContext(request))

I see two things here. On the view the method is not called. The method needs the () to be called.
Then the save_and_email method needs some corrections. First of all needs the self argument, or convert it to a .
My suggestion is as follows.
def save_and_email(self):
if self.is_valid():
contact = self.save(commit=False)
contact.timeOfMessage = datetime.now()
contact.answered = False
contact.save()
return True
else:
return False
And the view:
def contact(request):
if request.method == 'POST':
contactform = ContactForm(request.POST)
if contactform.save_and_email():
return HttpResponseRedirect('/contact/thankyou/')
return render_to_response('contact/contact.html', {'form': ContactForm()},
RequestContext(request))

Related

I Want To Add Permissions To User in Django?

i want to add user profile section for example superuser and simple_user so i can add permissions
But When I Submit my Registration Form I Get This Error:
AttributeError at /register/
'User' object has no attribute 'register'
How To Fix And Save User Profile Name?
Here is my Views.py
from django.shortcuts import render , get_object_or_404,redirect
from django.utils import timezone
from blog.models import *
from blog.forms import *
from django.contrib.auth.decorators import login_required
from django.urls import reverse_lazy
from django.contrib.auth.models import User
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import (TemplateView,ListView,
DetailView,CreateView,
UpdateView,DeleteView)
# Create your views here.
def user_register(request):
if request.method == "POST":
reg = register(request.POST or None)
if reg.is_valid():
user = reg.save()
user.profile = "simple_user"
user.set_password(user.password)
user.save()
else:
print(register.errors)
else:
reg = register()
return render(request,"registration/register.html",{'reg':reg})
Here is my Models.py
class register(models.Model):
user = models.OneToOneField(User,on_delete="Cascade", related_name="profile")
Here is my Forms.py
class register(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput(attrs={'class':'input-field'}))
class Meta():
model = User
fields = ('username','email','password')
Here is the Error Image:
Any Help Appreciated!
try this
user = reg.save()
p1 = register(user=user, #other colums if have) # register model
p1.save()
# user.profile = "simple_user"
user.set_password(user.password)
user.save()
hope it helps

Django NOT NULL constraint failed: BekanSite_project.owner_id

I have this problem:::
IntegrityError at /addproject/
NOT NULL constraint failed: BekanSite_project.owner_id. I do not know how I can fix this problem.
This is my model ::
from django.db import models
from django import forms
from django.contrib.auth.models import User
from django.core.validators import URLValidator
class Project(models.Model):
project_name = models.CharField(verbose_name='Имя
проекта',max_length=200, default='')
project_cost = models.IntegerField(verbose_name='Сумма
инвестиции',default='')
investor = models.IntegerField(verbose_name='Долья
инвестерa',default='')
email = models.EmailField(verbose_name='Почта',max_length=50,
default='')..other fields
owner = models.ForeignKey(User)
def __str__(self):
return self.owner
views.py
#login_required
def addproject(request):
if request.POST:
form = ProjectForm(request.POST, request.FILES)
if form.is_valid():
form.owner = request.user
addproject = form.save()"<<<<where it fails"
addproject.save()
return HttpResponseRedirect(reverse('accounts:profile'))
else:
form = ProjectForm()
return render(request, 'BekanSite/addproject.html',
{'form':form,'username':auth.get_user(request).username})
forms.py
from django.db import models
from django import forms
from .models import Project
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from PIL import Image
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = ['project_name','project_cost',...(other fields),]
I think it is somehow related to ForeignKey. Please help. Thanks beforehand.
You might want to attach the user before you check form is valid:
if request.POST:
form = ProjectForm(request.POST, request.FILES)
form.owner = request.user
if form.is_valid():
addproject = form.save()"<<<<where it fails"
addproject.save()
return HttpResponseRedirect(reverse('accounts:profile'))
And you dont have to call addproject.save() since form.save() does that already.
I have solved it. I don't know how it works, but I just added commit=False addproject = form.save(commit=False). I found it in the book "python-crash-course-a-hands-on-eric-matthes ". now it works.Also Thank you RajKris for your effort to solve this problem.Good luck.

Form data not getting saved in django

Since django User model had only few fields in it, I made a custom model and used it's ModelForm to save data to User model and the custom model. The models.py is as shown below
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
import datetime
class Post(models.Model):
Author=models.ForeignKey(User)
title=models.CharField(max_length=66)
content=models.TextField()
created_date=models.DateField(default=datetime.datetime.now())
published_date=models.DateField()
def publish(self):
self.published_date=datetime.datetime.now()
self.save()
class UserDetails(models.Model): #the custom model
uname=models.CharField(max_length=55)
first_name=models.CharField(max_length=55)
last_name=models.CharField(max_length=55)
age=models.IntegerField()
contact=models.CharField(max_length=13)
email=models.EmailField()
pword=models.CharField(max_length=55)
modelform :
class RegisterForm(ModelForm):
class Meta:
model=UserDetails
fields=['uname','pword','first_name','last_name','email','contact']
the views.py is like this
from django.shortcuts import render
from .models import UserDetails
# Create your views here.
from django.contrib.auth import authenticate,login,logout
from .forms import RegisterForm,LoginForm,PostForm
from django.contrib.auth.models import User
from django.db import IntegrityError
def register(request):
if request.method=='POST':
form=RegisterForm(request.POST)
try:
if form.is_valid():
form.save()
uname=form.cleaned_data['uname']
fname=form.cleaned_data['first_name']
pword=form.cleaned_data['pword']
email=form.cleaned_data['email']
contact=form.cleaned_data['contact']
lname=form.cleaned_data['last_name']
user=User.objects.create_user(uname,password=pword,email=email)
user.last_name=lname
user.save()
#form.save()
#stuff after registration
message="registration done! login again"
return render(request,'register.html',locals())
except IntegrityError:
message="username already exists!! try another"
else:
form=RegisterForm()
return render(request,'register.html',locals())
The problem is that even if I make a fresh entry to the RegisterForm, the 'message' I get is, username already exists!! try another. The auth.User model is getting updated but UserDetails is not. What am I doing wrong? (spare me if this is a stupid question :) )
update: 1
from django.shortcuts import render
from .models import UserDetails
# Create your views here.
from django.contrib.auth import authenticate,login,logout
from .forms import RegisterForm,LoginForm,PostForm
from django.contrib.auth.models import User
from django.db import IntegrityError
def register(request):
if request.method=='POST':
form=RegisterForm(request.POST)
try:
if form.is_valid():
form.save()
uname=form.cleaned_data['uname']
fname=form.cleaned_data['first_name']
pword=form.cleaned_data['pword']
email=form.cleaned_data['email']
contact=form.cleaned_data['contact']
lname=form.cleaned_data['last_name']
if not User.objects.filter(username=uname,email=email).exists():
user=User.objects.create_user(uname,password=pword,email=email)
user.last_name=lname
user.save()
message="registration done! login again"
return render(request,'register.html',locals())
except IntegrityError:
message="username already exists!! try another"
else:
form=RegisterForm()
return render(request,'register.html',locals())
if form.is_valid():
# save a UserDetails obj (data are automatically get from the form) to db.
form.save()
# Get data from form
uname = form.cleaned_data['uname']
fname = form.cleaned_data['first_name']
pword = form.cleaned_data['pword']
email = form.cleaned_data['email']
contact = form.cleaned_data['contact']
lname = form.cleaned_data['last_name']
# Check if user already exists. If it doesn't, create it
if not User.objects.filter(username=uname, email=email).exists():
user=User.objects.create_user(uname, password=pword, email=email)
#stuff after registration
message = "registration done! login again"
return render(request,'register.html',locals())
See more on the ModelForm's save() method.
However, I noticed that the age model field is required. So, the save() will complain. You should better make it as: age = models.IntegerField(blank=True, null=True) or define a default value like this age = models.IntegerField(default=20). Although, defining a default age is awkward, better follow the blank=True null=True to allow empty ages.
Age was missing in model form Fields

django check if model exist and return that to views.py

I am super new to django and I have the following problem.
I have some users in my Model "User" which has an email and a username field. I created a LoginFrom in my forms.py which only accepts an email address and checks if it exist in the User database. Then I want to return to my views.py and retrieve that model and work with it.
Very simple but, I cant do this
return email_get
in my forms.py as it says user already exists. The only way I can get back to views.py is by changing the form email that I got.
Something like,
email_got="found#gmail.com"
return email_got
So, how can I return to forms.py by keeping the original form email. Ps, I just want to manually check if user exist in database.
Here's my forms.py
from django import forms
from .models import User
class LoginForm(forms.ModelForm):
class Meta:
model=User
fields= ['email']
def clean_email(self):
email_got = self.cleaned_data.get('email')
if User.objects.filter(email=email_got).exists():
raise forms.ValidationError("Your email already exist")
return email_got
And my views.py
from django.conf import settings
from django.shortcuts import render
from django.core.mail import send_mail #for sending mail
from .forms import SignUpForm, LoginForm
from .models import User
def login(request):
username = None
form=LoginForm(request.POST or None)
if form.is_valid():
new_user = form.save()
username = getattr(new_user, 'username')
context = {
"form": form,
"username":username,
}
return render(request,"login.html",context)
Thanks a lot for the help!!
Okay so your isUser "validator" does not actually run at all. I can see you are doing custom validation on the email field but in order for django to know that you want isUser function called, you must follow the naming convention/requirement of clean_field_name(self). However because you are just doing a login check, you should just check if the email exists inside login(request).
So your forms.py:
from django import forms
from .models import User
class LoginForm(forms.ModelForm):
class Meta:
model=User
fields= ['email']
Your views.py should look like this:
from django.conf import settings
from django.shortcuts import render
from django.core.mail import send_mail #for sending mail
from .forms import SignUpForm, LoginForm
from .models import User
def login(request):
username = None
form=LoginForm(request.POST or None)
if form.is_valid(): # This part will just do the typical Django validation (no custom validation added now).
existing_user = User.objects.filter(email=form.cleaned_data.get('email')).first()
if existing_user: # The email provided exists in db.
username = existing_user.username
else: # email does not exist so do redirect
return redirect('name_of_your_sign_up_view')
context = {
"form": form,
"username":username,
}
return render(request,"login.html",context)

Dynamically remove a product from queryset if added to cart -- django

This is my original thought on how to accomplish this:
products = Product.objects.all()
for product in products:
if product in cart:
products = Product.objects.exclude(product)
My two questions are:
1.) Does this work/ make sense?
2.) Which .py file would I put it in?
views.py
from django.shortcuts import render
from django.shortcuts import HttpResponseRedirect
from django.core.urlresolvers import reverse
from .models import Dropoff, DropoffItem
from products.models import Product
from .forms import AddDropoffItemForm
from django.contrib.auth.models import User
from django.contrib import messages
from django.contrib.auth.decorators import login_required
def add_item_dropoff_order(request):
request.session.set_expiry(120000)
try:
user = request.user
the_id = request.session['dropoff_id']
dropoff = Dropoff.objects.get(id=the_id)
except:
user = request.user
new_dropoff_order = Dropoff(user=user)
new_dropoff_order.save()
request.session['dropoff_id'] = new_dropoff_order.id
the_id = new_dropoff_order.id
dropoff = Dropoff.objects.get(id=the_id)
try:
product = Product.objects.get(sku=sku)
except Product.DoesNotExist:
pass
except:
pass
form = AddDropoffItemForm(request.POST or None)
if request.method == "POST":
product_sku = str(request.POST['product'])
dropoff_item = DropoffItem.objects.create(dropoff=dropoff, product_id=product_sku)
dropoff_item.save()
return HttpResponseRedirect('%s'%(reverse('add_item_dropoff_order')))
context = {
"dropoff": dropoff,
"form": form,
}
return render(request, 'dropoffs/add_item_dropoff_order.html', context)
forms.py
from django import forms
from .models import Dropoff, DropoffItem
from products.models import Product
class AddDropoffItemForm(forms.ModelForm):
product = forms.ModelChoiceField(queryset=Product.objects.all(), widget=forms.Select(attrs={'class':'form-control'}))
class Meta:
model = DropoffItem
fields = ["product"]
So basically, once dropoff_item.save() occurs, I want to remove that product from the queryset being called in the forms.py file.
Is it possible to redefine the queryset in the views and then call it again in the forms.py?
No, not really :) I would approach this like:
products = Product.objects.exclude(id__in=cart.product_ids)
Without seeing your application logic, it's impossible to tell you where to put this code, but since you've tagged django views, I'm assuming you want it in a view.