ForeignKey Error at Django - python

i spend a lot of hours searching for such an error but didn't found anything,
as you know Djangov2.00 requires you to set on_delete=*** with ForeignKey and here i can't do a ForeignKey anymore.
my Models.py
from django.db import models
class makereport(models.Model):
Name = models.CharField(max_length=50)
VID = models.IntegerField()
Callsign = models.CharField(max_length=6)
Date = models.DateField(default='yy-mm-dd')
SelectAward = models.CharField(max_length=50, choices=(('1', 'Division Online Day'), ('2', 'Pilot Event'), ('3', 'ATC Event'), ('4', 'Pilot Event')))
done = models.ForeignKey('reports', on_delete=models.CASCADE)
# reports.ATC = reports.ATC + 1
def __str__(self):
return self.Name
class reports (models.Model):
Name = models.CharField(max_length=50)
VID = models.IntegerField()
DivisionOnline = models.IntegerField(default=0)
ATCEvent = models.IntegerField(default=0)
PilotEvent = models.IntegerField(default=0)
PilotSupport = models.IntegerField(default=0)
ATC = 0
def __str__(self):
return self.Name
and the Error
django.db.utils.IntegrityError: Not Null constraint failed: report_makereport.done_id
i don't know what to do with that id ,versions before V2 was working.
Views.py
from django.db import IntegrityError
from django.http import HttpResponse, request
from django.shortcuts import render, redirect
# Create your views here.
from django.views import View
from report import models
from report.forms import RepForm
from report.models import makereport, reports
class home(View):
def get(self,request):
form = RepForm()
reps = reports.objects.all()
rep = makereport.objects.all()
context = {
'rep':rep,
'form' : form,
'reps':reps
}
return render(request,'home.html',context)
def post(self,request):
form = RepForm(request.POST)
if form.is_valid():
repo = makereport()
repo.Name = form.cleaned_data['Name']
repo.VID = form.cleaned_data['VID']
repo.Callsign = form.cleaned_data['Callsign']
repo.Date = form.cleaned_data['Date']
repo.SelectAward = form.cleaned_data['SelectAward']
repo.done = None
try:
repo.save()
return redirect('/')
except IntegrityError:
context = {'form':form,
'error_msg': 'Error,Please Check your Information'}
return render(request, 'home.html', context)
else:
return self.get(request)

The way you set up this field done = models.ForeignKey('reports', on_delete=models.CASCADE) means that this field can't remain empty nor null.
When you createe a makereport object, this field must have a report instance, if not IntegrityError: Not Null will raise
In case of creating makereport object without a report instance. the following can do it
done = models.ForeignKey('reports',
on_delete=models.SET_NULL,null=True,blank=True)
in your views, try this:
''' codes '''
repo.done = None
repo.save()

Related

Why am I getting 'Foreign Key Mismatch' when trying to save a model form in Django?

I am trying to save an instance of a modelform in Django. I have setup a template to input information to the form and a view to handle the save. The form validates fine, but when trying to save it generates a foreigkey mismatch error. What am I doing wrong here?
I am running Django 2.0.0. I have already tried adding and removing the primary_key option without any luck and deleting my sqlite database, clearing all pycache, and migrating again. The problem persists.
#models.py
from django.db import models
import uuid
from users.models import Company, CustomUser
from delivery import settings
class Location(models.Model):
location_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
address = models.CharField(max_length = 120)
date_added = models.DateField(auto_now_add = True)
class Shipment(models.Model):
date_created = models.DateField(auto_now_add=True)
sender_company = models.ForeignKey(Company, on_delete = models.PROTECT, related_name='sender')
receiver_company = models.ForeignKey(Company, on_delete = models.PROTECT, related_name='receiver')
origin = models.ForeignKey(Location, on_delete = models.SET_DEFAULT, default = 'Location no longer active.', related_name='origin')
destination = models.ForeignKey(Location, on_delete = models.SET_DEFAULT, default = 'DESTINATION UNKNOWN', related_name='destination')
expected_arrival = models.DateField()
weight = models.FloatField()
current_handler = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete = models.SET_DEFAULT, default = 'UNKNOWN')
shipment_id = models.UUIDField(unique=True, primary_key = True, default=uuid.uuid4, editable=False)
#forms.py
from django import forms
from .models import Location, Shipment
class LocationRegisterForm(forms.ModelForm):
class Meta:
model = Location
fields = '__all__'
class CreateShipment(forms.ModelForm):
class Meta:
model = Shipment
exclude = ['current_handler', 'shipment_id']
def clean_expected_arrival(self):
expected_arrival = self.cleaned_data['expected_arrival']
date_created = self.cleaned_data['date_created']
if expected_arrival < date_created:
raise ValidationError('Expected arrival date cannot be in the past.')
return expected_arrival
#views.py
from django.shortcuts import render, redirect
from .forms import CreateShipment, LocationRegisterForm
from users.permissions import group_required
#group_required('delivery_employee')
def new_shipment(request):
if request.method == 'POST':
form = CreateShipment(request.POST)
if form.is_valid():
temp_form = form.save(commit=False)
current_user = request.user
temp_form.current_handler = current_user
temp_form.save()
return redirect('dash-home')
else:
return render(request, 'shipments/new-shipment.html', {'form':form})
form = CreateShipment()
return render(request, 'shipments/new-shipment.html', {'form':form})
#group_required('delivery_employee')
def add_location(request):
if request.method == 'POST':
form = LocationRegisterForm(request.POST)
if form.is_valid():
form.save()
return redirect('new-shipment')
else:
return render(request, 'shipments/location-register.html', {'form':form})
form = LocationRegisterForm()
return render(request, 'shipments/location-register.html', {'form':form})
I get the error message:
File "C:\Python34\lib\site-packages\django\db\backends\sqlite3\base.py", line 303, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: foreign key mismatch - "shipments_shipment" referencing "shipments_location"
Thank you!
Your origin and destination fields set default value to plain strings, their default values should be the default Location instances instead.
Create methods like get_default_origin and get_default_destination where you will return the existing records from the database. Assign those methods to default argument, like
origin = models.ForeignKey(Location, on_delete = models.SET_DEFAULT, default=self.get_default_origin, related_name='origin')
destination = models.ForeignKey(Location, on_delete = models.SET_DEFAULT, default=self.get_default_destination, related_name='destination')

Cannot resolve keyword 'id' into field. Choices are: complete, task_priority, text, user, user_id

I am working on a Todo list which has seperate users with their own list.
Initially I had the models.py as:
from django.db import models
from django.contrib.auth.models import User
class Todo(models.Model):
text = models.CharField(max_length=40, default='Test User')
complete = models.BooleanField(default = False)
task_priority = models.CharField(max_length=40, default='high')
def __str__(self):
return self.text
But then when im trying to link single user with its own set of todotask(text field) and its priorites and status.
I added one to one field like this:
from django.db import models
from django.contrib.auth.models import User
class Todo(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE,primary_key='user_id') #new
text = models.CharField(max_length=40, default='Test User')
complete = models.BooleanField(default = False)
task_priority = models.CharField(max_length=40, default='high')
def __str__(self):
return self.text
It threw an error like this:
FieldError at /
Cannot resolve keyword 'id' into field. Choices are: complete, task_priority, text, user, user_id
I didnt completely understand the concept of one to one fields and looking at the tutorials online im confused weather I need to make another table and link it to the Todo table or add another field with some primary key?
Help me understand this concept.
Thanks in advance.
EDIT:
views.py file:
from django.shortcuts import render, redirect
from .models import Todo
from .form import TodoForm,ContactForm
import datetime
from django.conf import settings
from django.utils import timezone
from django.views.decorators.http import require_POST
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse, HttpResponseRedirect
import json
def index(request):
todo_list = Todo.objects.order_by('id')
form = TodoForm()
mydate = datetime.datetime.now()
context = {'todo_list': todo_list, 'form': form, 'mydate':mydate}
return render(request,'todo/index.html',context)
def login(request):
return render(request, 'todo/login.html')
#require_POST
def addTodo(request):
form = TodoForm(request.POST)
text_input = form.get_cleaned_data['text']
priority_input = form.get_cleaned_data['task_priority']
if form.is_valid():
new_todo = Todo(text = text_input, task_priority = priority_input)
# new_todo = Todo(text = request.POST['text'])
new_todo.save()
return redirect('index')
def completeTodo(request, todo_id):
todo = Todo.objects.get(pk=todo_id)
todo.complete = True
todo.save()
return redirect('index')
def deleteCompleted(request):
Todo.objects.filter(complete__exact=True).delete()
return redirect('index')
def deleteAll(request):
Todo.objects.all().delete()
return redirect('index')
def emailView(request):
todo = Todo.objects.all();
task_list = []
status_list = []
for item in todo:
stritem=str(item)
task_list.append(stritem)
if item.complete == True:
status_list.append('complete')
else:
status_list.append('incomplete')
if request.method == 'GET':
form = ContactForm()
else:
form = ContactForm(request.POST)
if form.is_valid():
from_email = form.cleaned_data['from_email']
message = form.cleaned_data['message']
#maillist = Todo.objects.all()
email_list=dict(zip(task_list,status_list))
strlist = json.dumps(email_list)
content = message + strlist
try:
send_mail('Todo List', content ,settings.EMAIL_HOST_USER,[from_email])
except BadHeaderError:
return HttpResponse('Invalid header found.')
return redirect('success')
return render(request, "email.html", {'form': form})
def successView(request):
return HttpResponse('Success! Thank you for your message.')
New models.py:
from django.db import models
from django.contrib.auth.models import User
class Todo(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
text = models.CharField(max_length=40, default="")
complete = models.BooleanField(default = False)
task_priority = models.CharField(max_length=40, default='high')
def __str__(self):
return self.text
Encountered
IntegrityError at /add NOT NULL constraint failed: todo_todo.user_id
This:
user = models.OneToOneField(User,on_delete=models.CASCADE,primary_key='user_id')
isn't at all doing what you think it is. primary_key expects a boolean, not a field name, and isn't to do with the relationship at all. Because the string 'user_id' is not empty, this is being interpreted as True, and is equivalent to:
user = models.OneToOneField(User,on_delete=models.CASCADE,primary_key=True)
which means that user is now the primary key for the Todo model. This is not what you want.
Remove that primary_key clause.

type object 'Cart' has no attribute 'objects' in django website

I am trying to learn to make cart in e-commerce website by watching some tutorial. I get an error while running my code although it works fine in the tutorial but in my code, it gives error something like this. I have no idea why I tried to check my code several time but still I am unable to figure out.
type object 'Cart' has no attribute 'objects'
These are my codes
carts/models.py
from django.conf import settings
from django.db import models
from products.models import Product
User = settings.AUTH_USER_MODEL
# Create your models here.
class CartManager(models.Manager):
def new(self, user=None):
user_obj = None
if user is not None:
if user.is_authenticated():
user_obj = user_obj
return self.model.objects.create(user=user_obj)
class Cart(models.Model):
user = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
products = models.ManyToManyField(Product, blank=True)
total = models.DecimalField(default=0.00, max_digits=100, decimal_places=2)
updated = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
object = CartManager()
def __str__(self):
return str(self.id)
carts/view
from django.shortcuts import render
from .models import Cart
# Create your views here.
def cart_home(request):
cart_id = request.session.get('cart_id', None)
qs = Cart.objects.filter(id = cart_id)
if qs.count() == 1:
cart_obj = qs.first()
print('Cart id exists')
else:
cart_obj = Cart.objects.new(user=request.user)
request.session['cart_id'] = cart_obj.id
return render(request, "carts/home.html", {})
Because of this:
class Cart(models.Model):
...
object = CartManager()
You have assigned the model manager as attribute object in Cart model. So rename it to objects.

Assign a serial number when quantity is more than one

I have a model in which a unique serial number is generated, and there is a quantity field in which the user can select how many parts they'd like made. Think of it like a shopping order. I'd like that if the user selects a quantity of more than one, a serial number be assigned to each individual part.
Models:
from __future__ import unicode_literals
from tande.models import Project, Person
from django.db import models
from django.utils import timezone
from django.utils.text import slugify
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
from django.db.models.signals import pre_save
from django.conf import settings
# Create your models here.
class buildrisk(models.Model):
risk = models.CharField(max_length=20, default = 'Select Risk')
def __unicode__ (self):
return self.risk
class sens(models.Model):
sens = models.CharField(max_length=20, default = 'Select Sensitivity')
def __unicode__ (self):
return self.sens
class MOI(models.Model):
method = models.CharField(max_length=20, default = 'Select Method')
def __unicode__ (self):
return self.method
def number():
no = PartRequest.objects.count()
if no == None:
return "PR00001"
else:
return "PR00" + str(no + 100)
def snumber():
no = PartRequest.objects.count()
add = sum(map(int, str(no)))
if no == None:
return "SN00001"
else:
return "SN00" + str(no + 100 + add)
# while n:
# sn, n = sn + n % 10, n // 10
# return sn
class PartRequest(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
part_request_number = models.CharField(_('Part Request Number'),max_length=10, default = number)
serialnumber = models.CharField(_('Serial Number'),max_length=10, default= snumber)
project_manager = models.ForeignKey(Person, related_name = 'Manager', null = True)
requester = models.ForeignKey(Person, related_name = 'Requester', null = True) #drop down
project_id = models.ForeignKey(Project, related_name = 'Project', null=True)
ordernumber = models.PositiveIntegerField(_('Order Number'), default=0)
description = models.CharField(_('Description'), max_length=500)
quantityrequired = models.PositiveIntegerField(_('Quantity'), default=0)
sensitivity = models.ForeignKey(sens, related_name='sensitivity', null=True) #drop down
identification_method = models.ForeignKey(MOI, related_name= 'MOI', null=True)
build_risk = models.ForeignKey(buildrisk, related_name= 'Risk', null=True)
daterequired = models.DateField(_('Date Required'), default = '04/08/16')
slug = models.SlugField(unique=True, null=True)
def __str__(self):
return unicode(self.requester)
def get_absolute_url(self):
return "/buildpage/%s/" %(self.slug)
#return ("buildpage:page3", kwargs = {"slug": self.slug})
def create_slug(instance, new_slug=None):
slug = slugify(instance.part_request_number)
if new_slug is not None:
slug = new_slug
qs = PartRequest.objects.filter(slug=slug).order_by("-id")
exists = qs.exists()
if exists:
new_slug = "%s-%s" %(slug, qs.first().id)
return create_slug(instance, new_slug=new_slug)
return slug
def pre_save_receiver(sender, instance, *args, **kwargs):
if not instance.slug:
instance.slug = create_slug(instance)
pre_save.connect(pre_save_receiver, sender = PartRequest)
Views:
from django.shortcuts import render, get_object_or_404, redirect, get_object_or_404
from django.contrib import messages
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.template import RequestContext, loader
from django.contrib.auth.decorators import login_required
from .forms import PartRequestForm
from .models import PartRequest
from tande.models import Project, Person
# Create your views here.
#login_required
def home(request):
latest_project_list = Project.objects.all()
context = {'latest_project_list': latest_project_list}
return render(request, 'buildpage/home.html', context)
def partrequestinfo(request):
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
req_form = PartRequestForm(request.POST or None, request.FILES or None)
if req_form.is_valid():
instance = req_form.save(commit=False)
instance.user = request.user
print request.POST
print req_form.cleaned_data.get("requester")
print instance
instance.save()
messages.success(request, "Successfully Created")
return HttpResponseRedirect(instance.get_absolute_url())
else:
context = {
"req_form": req_form
}
return render(request, "buildpage/partrequestinfo.html", context)
def partrequestdetail(request, slug=None):
print "in partrequestdetail function"
instance = get_object_or_404(PartRequest, slug=slug)
context = {
"project_id": instance.project_id,
"instance": instance,
}
return render(request, 'buildpage/partrequestdetail.html', context)
def partrequestupdate(request, slug=None):
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
instance = get_object_or_404(PartRequest, slug=slug)
req_form = PartRequestForm(request.POST or None, request.FILES or None, instance=instance)
if req_form.is_valid():
instance = req_form.save(commit=False)
print request.POST
print req_form.cleaned_data.get("requester")
print instance
instance.save()
messages.success(request, "Saved")
return HttpResponseRedirect(instance.get_absolute_url())
context = {
"project_id": instance.project_id,
"instance": instance,
"req_form": req_form,
}
return render(request, 'buildpage/partrequestinfo.html', context)
def partrequestdelete(request, slug=None):
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
instance = get_object_or_404(PartRequest, slug=slug)
messages.success(request, "Successfully Deleted")
return redirect("buildpage:home")
def preparebuildlist(request, slug=None):
return render(request, 'buildpage/preparebuildlist.html')
I can't really understand your models, but I think what you need (if you don't already have it) is a Part model. Have one field in the Part model be the serial number of the part, which can be automatically generated if you want, and so when a user requests X number of parts you can just create and save X Part objects.

django user authentication incorporated with models and views

I still cant seem to put a simple program together. I am thinking of a simple program where my coworkers and I could propose a bet with each other. (example: I bet the detriot Lions dont win another game this season) If someone is feeling up to the task of taking that bet they can just hit an accept button. I want the user to be logged in and upon submitting the bet_name and bet_desc of the bet, their username, bet_name, bet_desc, and timestamp is saved to a table. Then a relationship table would save the bet id, win, tie, created_user_id, accepted_user_id, accepted_timestamp, and cancelled. Then userprofile table to keep their username, wins, losses, ties, bets_made, and bets_accepted.
models.py
from django.db import models
from django.contrib.auth.models import User
from datetime import datetime
class UserProfiles(models.Model):
username = models.OneToOneField(User)
wins = models.PositiveIntegerField(default=0)
losses = models.PositiveIntegerField(default=0)
ties = models.PositiveIntegerField(default=0)
bets_made = models.PositiveIntegerField(default=0)
bets_accepted = models.PositiveIntegerField(default=0)
def __str__(self):
return "%s's profile" % self.username
class Bets2(models.Model):
bet_name = models.CharField(max_length=30)
bet_desc = models.CharField(max_length=300)
timestamp = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
created_user = models.OneToOneField(UserProfiles, primary_key=True)
accepted_user = models.PositiveIntegerField(default=0)
accepted_timestamp = models.DateTimeField(auto_now=True)
win = models.BooleanField(default=True)
tie = models.BooleanField(default=True)
cancelled = models.BooleanField(default=True)
def __str__(self):
return "%s's profile" % self.bet_name
As far as forms.py and views this is all i have so far:
forms.py
from django import forms
from django.core.exceptions import ValidationError
from .models import Bets2, UserProfiles
class BetForm(forms.ModelForm):
class Meta:
model = Bets2
fields = ['bet_name', 'bet_desc',]
def clean_name(self):
bet_name = self.cleaned_data.get('bet_name')
#write code here
return name
def clean_bet(self):
bet_desc = self.cleaned_data.get('bet_desc')
#write code here
return bet
views.py
from django.shortcuts import render
from django.conf import settings
from .forms import BetForm
from .models import Bets2, UserProfiles
def home(request):
title = "2015 Boardbets"
queryset = Bets2.objects.all().order_by('timestamp')
queryuser = UserProfiles.objects.all()
context = {
"title": title,
"queryset" : queryset,
"queryuser" : queryuser,
}
return render(request, "home.html", context)
def boardbet(request):
form = BetForm(request.POST or None)
bet_variables = Bets2.objects.all()
context = {
"form" : form,
"bet_variables" : bet_variables,
}
if form.is_valid():
form.save()
return render(request, "bets.html", context)
This is where i get stumped, i dont know how to incorporate the other two models into the view so that all three tables get created and also how to reference them in the template.
Edit: changed it to one model for Bets

Categories

Resources