Cannot assign "u''": "Company.parent" must be a "Company" instance - django

I am getting this at every attempt.
Cannot assign "u''": "Company.parent" must be a "Company" instance.
I do not know what else to do.
The view code is still half baked, sorry for that.
Am I passing wrong parameters to the form?
I have the following model:
models.py
class Company(AL_Node):
parent = models.ForeignKey('self',
related_name='children_set',
null=True,
db_index=True)
node_order_by = ['id', 'company_name']
id = models.AutoField(primary_key=True)
company_name = models.CharField(max_length=100L, db_column='company_name') # Field name made lowercase.
next_billing_date = models.DateTimeField()
last_billing_date = models.DateTimeField(null=True)
weekly = 'we'
twice_a_month = '2m'
every_two_weeks = '2w'
monthly = 'mo'
billing_period_choices = (
(weekly, 'Weekly'),
(every_two_weeks, 'Every two weeks'),
(twice_a_month, 'Every two weeks'),
(monthly, 'Monthly'),
)
billing_period = models.CharField(max_length=2,
choices=billing_period_choices,
default=weekly)
objects = CompanyManager()
The following forms.py:
class newCompany(ModelForm):
company_name = forms.CharField(label='Company Name',
widget=forms.TextInput(attrs={'class': 'oversize expand input-text'}))
billing_period = forms.ModelChoiceField
next_billing_date = forms.CharField(widget=forms.TextInput(attrs={'class': 'input-text small', 'id': 'datepicker'}))
parent = forms.CharField(widget=forms.HiddenInput(), required=False)
class Meta:
model = Company
fields = ["company_name", "parent", "billing_period", "next_billing_date"]
The following view:
def create_company(request):
userid = User.objects.get(username=request.user).id
my_company_id = CompanyUsers.objects.get(user_id=userid).company_id
my_company_name = Company.objects.get(id=my_company_id).company_name
machines = Title.objects.raw(
'select machines.id, title.name, machines.moneyin, machines.moneyout, moneyin - moneyout as profit, machines.lastmoneyinoutupdate, (select auth_user.username from auth_user where machines.operator = auth_user.id) as operator, (select auth_user.username from auth_user where machines.readers = auth_user.id) as readers from machines, title where machines.title = title.id and machines.company_id =%s',
[my_company_id])
if request.method == 'POST':
form_company = newCompany(request.POST)
if form_company.is_valid():
new_company = form_company.save(commit=False)
new_company.parent = my_company_id
if request.POST.get('select_machine'):
selected_machine = request.POST.getlist('select_machine')
percentage = request.POST.get('percentage')
if not Beneficiary.objects.check_assign_machine(my_company_id, selected_machine, percentage):
target_company_name = new_company.company_name
target_company_id = Company.objects.get(company_name=target_company_name).id
new_company.save()
Machines.objects.assign_machine(target_company_id, selected_machine)
Beneficiary.objects.create_beneficiary(percentage, target_company_name, my_company_id, selected_machine)
else:
invalid_machines = Beneficiary.objects.check_assign_machine(my_company_id, selected_machine, percentage)
return render(request, 'lhmes/createcompany.html',
{'form_company': form_company, 'machines': machines, 'my_company_name': my_company_name, 'invalid_machines' : invalid_machines})
else:
new_company.save()
else:
form_company = newCompany()
return render(request, 'lhmes/createcompany.html',
{'form_company': form_company, 'machines': machines, 'my_company_name': my_company_name})

The error message says you are trying to set a relationship with a string but Django expects the value to be an instance of the Company model. You should assign the foreign key fields with a real model instance instead of only the primary key.
I've spotted a few places in the code where you are assigning a PK:
new_company.parent = my_company_id
Where the model expects it to be an instance:
new_company.parent = Company.objects.get(id=my_company_id)
I really don't remember if this works, but you can try:
new_company.parent_id = int(my_company_id)
This would spare a trip to the database.

Related

Django Foreign Keys connections

I have a model Field that has a OneToMany connections with TreeSensor and WeatherStation model. Im trying to pass over the queries of each treesensor/weatherstation model that match the id of each different field but get a Field 'id' expected a number but got <built-in function id>. .How do i fix that? Maybe change something on the filter ?
class Field(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True, default=None)
friendly_name = models.CharField(max_length=24, blank=True)
soil_type = models.CharField(max_length=24, choices=SOIL_TYPES, blank=True)
cultivation = models.CharField(max_length=128, choices=CULTIVATIONS, blank=True)
kml = models.FileField(upload_to = user_directory_path_kml, null=True, blank=True)
class TreeSensor(models.Model):
field = models.ForeignKey(Field, on_delete=models.CASCADE)
...
class WeatherStation(models.Model):
field = models.ForeignKey(Field, on_delete=models.CASCADE)
...
view
def map(request):
field_list = models.Field.objects.filter(user = request.user)
tree_sensors = models.TreeSensor.objects.filter(field__pk = id)
weather_stations = models.WeatherStation.objects.filter(field__pk = id)
context = {
"title": "Map",
"field_list": field_list,
"tree_sensors": tree_sensors,
"weather_stations" : weather_stations,
}
template = 'agriculture/map.html'
return render(request, template, context)
On your view you are filtering some field called field by id, which is not defined nowehere....
You have a queryset of Fields, so probably you should do something like this:
def map(request):
field_list = models.Field.objects.filter(user = request.user).values_list('id', flat=True)
tree_sensors = models.TreeSensor.objects.filter(field__id__in = field_list)
weather_stations = models.WeatherStation.objects.filter(field__id__in = field_list)
#Walucas your approach was correct it was kinda different though . It works out like this :
view
def map(request):
field_list = models.Field.objects.filter(user = request.user)
tree_sensors = models.TreeSensor.objects.filter(field_id__in = field_list.values_list('id',flat=True))
weather_stations = models.WeatherStation.objects.filter(field_id__in = field_list.values_list('id',flat=True))
context = {
"title": "Map",
"field_list": field_list,
"tree_sensors": tree_sensors,
"weather_stations" : weather_stations,
}
template = 'agriculture/map.html'
return render(request, template, context)

Value Error:Cannot assign queryset to attribute it must be instance

I have models.py
class employees(models.Model):
emp_id=models.PositiveIntegerField()
emp_name = models.CharField(max_length = 100)
emp_lname = models.CharField(max_length = 100)
emp_loc=models.CharField(max_length=5,choices=LOCATION)
manager_id=models.ForeignKey('self',null=True,blank=True)
class leave(models.Model):
employee = models.ForeignKey(employees, on_delete=models.CASCADE, default='1')
start_date = models.DateField()
end_date = models.DateField()
status=models.CharField(max_length=1,choices=LEAVE_STATUS,default='P')
ltype=models.CharField(max_length=2,choices=LEAVE_TYPE)
message=models.CharField(max_length=500,blank=True)
class notify(models.Model):
sender_id=models.ForeignKey(leave, related_name='%(class)s_sendername')
receiver_id=models.ForeignKey(leave,related_name='%(class)s_receivername')
date_time=models.DateTimeField()
I have views.py
def accept(request):
approved_emp_id=leave.objects.filter(id=accept_id);
approving_emp_id=leave.objects.filter(employee__emp_id=request.user.username);
accept_notify=notify(sender_id=approving_emp_id, receiver_id=approved_emp_id,date_time=datetime.datetime.now(),viewed='N');
accept_notify.save()
When I want to save values to database I am getting error as ValueError: Cannot assign "<QuerySet [<leave: 121-geeta-2017-10-04-2017-10-06-C-V-2017-09-27 07:48:36.288873+00:00>]>": "notify.sender_id" must be a "leave" instance.
Where am I going wrong approving_emp_id and approved_emp_id are both leave instance only.
You are passing a QuerySet when the arguments should be an instance. A QuerySet is a list of instances. Pass only one instance. Use leave.objects.get() instead of leave.objects.filter().
objects.get() returns a single instance where objects.filter() returns a QuerySet.
def accept(request):
approved_emp_id = leave.objects.get(id = accept_id)
approving_emp_id = leave.objects.get(employee__emp_id = request.user.username)
accept_notify = notify(sender_id = approving_emp_id, receiver_id = approved_emp_id, date_time = datetime.datetime.now(), viewed = 'N')
accept_notify.save()
Another way is slicing the QuerySet.
def accept(request):
approved_emp_id = leave.objects.filter(id = accept_id)[0]
approving_emp_id = leave.objects.filter(employee__emp_id = request.user.username)[0]
accept_notify = notify(sender_id = approving_emp_id, receiver_id = approved_emp_id, date_time = datetime.datetime.now(), viewed = 'N')
accept_notify.save()

Cannot assign "42": "Event.user_id" must be a "User" instance

I have checked all the solutions related to my question but no one worked, i have an event table in which i am assigning the id of user. Event Model is
class Event(models.Model):
user_id=models.ForeignKey(User, on_delete=models.CASCADE)
event_auth_id=models.CharField(null=True, max_length=225)
event_title=models.CharField(max_length=225)
ticket_title=models.CharField(max_length=225)
category=models.CharField(max_length=50)
event_summary=models.TextField()
event_information=models.TextField()
restriction=models.CharField(max_length=50, default='No Restriction')
artist_image=models.CharField(null=True, max_length=50)
event_poster=models.CharField(null=True, max_length=50)
notification_email=models.CharField(null=True, max_length=50)
notification_frequency=models.CharField(null=True, max_length=15)
name_on_ticket=models.CharField(max_length=225)
event_tnc=models.TextField()
current_step=models.IntegerField(null=True)
event_status=models.BooleanField(default=True)
created=models.DateTimeField(auto_now=True)
modified=models.DateTimeField(auto_now_add=True)
I am assigning the logged in user id from view
def create_new_event(request, steps):
if request.method == 'POST':
if(steps=="step_1"):
stepFirstForm = CreateEventStepFirstForm(request.POST)
if stepFirstForm.is_valid():
eventStepFirst = Event(
user_id = request.user.id,
event_auth_id = uuid4(),
event_title = request.POST['event_title'],
ticket_title = request.POST['ticket_title'],
category = request.POST['categories'],
event_summary = request.POST['event_summary'],
event_information = request.POST['event_information'],
restriction = request.POST['restrictions'],
notification_email = request.POST['notification_email'],
notification_frequency = request.POST['email_frequency']
)
But its giving me error
Cannot assign "42": "Event.user_id" must be a "User" instance.
The problem is in this code:
def create_new_event(request, steps):
if request.method == 'POST':
if(steps=="step_1"):
stepFirstForm = CreateEventStepFirstForm(request.POST)
if stepFirstForm.is_valid():
eventStepFirst = Event(
user_id = request.user.id,
event_auth_id = uuid4(),
event_title = request.POST['event_title'],
ticket_title = request.POST['ticket_title'],
category = request.POST['categories'],
event_summary = request.POST['event_summary'],
event_information = request.POST['event_information'],
restriction = request.POST['restrictions'],
notification_email = request.POST['notification_email'],
notification_frequency = request.POST['email_frequency']
)
In the place of "user_id = request.user.id" You should use "user_id = request.user" or "user_id = request.user.username" because in the field
user_id=models.ForeignKey(User, on_delete=models.CASCADE)
of Event model,you assigned user_id as a foreign key of User model,So user_id field is expecting a User instance,not request.user.id
Thanks.
The ForeignKey field is expecting an object of type User, not the user ID. Try changing the assignment user_id = request.user.id to user_id = request.user. It might also make sense to rename the field to "user" to avoid confusion in the future.

Django foreign key is not set and hence unable to save form

I have a simple foreign key relationship between two tables. I am able to save the parent, but am unable to save the child which has a foreign key to the parent. This is what my models look like:
class Product(models.Model):
month_choices = tuple((m,m) for m in calendar.month_abbr[1:])
year_choices = tuple((str(n), str(n)) for n in range(2004, datetime.now().year +2 ))
id = models.AutoField(primary_key = True)
title = models.CharField(max_length = 1024)
product_type = models.ForeignKey(ProductType)
month = models.CharField(max_length =3, choices=month_choices)
year = models.CharField(choices=year_choices, max_length = 4)
project = models.CharField(max_length = 15, null = True, blank = True)
url = models.URLField(null = True, blank = True)
export_to_xsede = models.BooleanField()
#def __str__(self):
# return str(self.id)
class Meta:
db_table = "product"
class ProductResource(models.Model):
CHOICES = (('A','A'),('B','B'),('C','C'),('D','D'),('E','E'))
id = models.AutoField(primary_key = True)
product = models.ForeignKey(Product)
resource = models.CharField(choices=CHOICES, max_length = 15)
And my views:
class PublicationForm(forms.ModelForm):
title = forms.CharField(widget=forms.TextInput(attrs={'size':'70'}),required=False)
url = forms.CharField(widget=forms.TextInput(attrs={'size':'70'}),required=False)
class Meta:
model = Product
class ResourceForm(forms.ModelForm):
resource = forms.MultipleChoiceField(choices=ProductResource.CHOICES, widget = forms.CheckboxSelectMultiple)
class Meta:
model = ProductResource
I save the parent:
saved_publication = publications_form.save()
but am unable to save the resource form:
resource_form = ResourceForm(request.POST, instance = saved_publication)
resource_form.product = saved_publication
resource_form.save()
When I print resource_form.errors, I get:
<ul class="errorlist"><li>product<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
I have no idea why the foreign key is not getting set in this case.
I'm assuming you do not want to display the product field on the form, so you should exclude it from the form so the validation will pass:
class ResourceForm(forms.ModelForm):
resource = forms.MultipleChoiceField(choices=ProductResource.CHOICES, widget = forms.CheckboxSelectMultiple)
class Meta:
model = ProductResource
exclude = ['product']
Then in the view, just set the product manually after calling is_valid(). Just be sure to pass commit=False on the form.save() so that it will not actually save to the database until after you set the product. For example
...
saved_publication = publications_form.save()
resource_form = ResourceForm(request.POST)
if resource_form.is_valid():
resource = resource_form.save(commit=False)
resource.product = saved_publication
resource.save()

Django: Form save method

I have a form, working off different models and using a through (intermediate) model:
class CourseBooking(BaseModel):
'''Intermediary model linking a person on a course with the related booking'''
course = ForeignKey('ScheduledCourse')
customer = ForeignKey('Customer')
booking = ForeignKey('GroupBooking', blank=True, null=True)
The form is using a basic form instead of Model form, with the fields added in manually:
class CourseBookingForm(Form):
course = ModelChoiceField(queryset=ScheduledCourse.objects.all())
title = CharField(
max_length=255,
widget=Select(choices=TITLE_CHOICES),
required=False
)
gender = CharField(
max_length=255,
widget=Select(choices=GENDER_CHOICES),
required=False
)
first_name = CharField(max_length=255)
surname = CharField( max_length=255)
dob = DateField(required=False)
medical = CharField(required=False, widget = forms.Textarea(attrs={'rows': '4'}))
# miscellaneous notes
notes = CharField(required=False, widget = forms.Textarea(attrs={'rows': '4'}))
email = EmailField(required=False)
phone = CharField(required=False)
address = CharField(
max_length=8188,
widget=Textarea(attrs={'rows':'4', 'cols':'50'}),
required=False)
city = CharField(max_length=255, required=False)
county = CharField(
max_length=255, widget=Select(choices=COUNTY_CHOICES))
postcode = CharField(max_length=255, required=False)
country = CharField(
max_length=255,
widget=Select(choices=COUNTRIES), required=False)
I want to create a save method in the forms.py which will save to the database. What I have at the moment (which is wrong) is and gives the error: IntegrityError: null value in column "customer_id" violates not-null constraint
def save(self):
data = self.cleaned_data
if self.cleaned_data['course']:
crs = self.cleaned_data['course']
course_booking = CourseBooking(course=crs)
course_booking.save()
course = CourseBooking.objects.create(course=data['course'])
course.save()
cust = Customer.objects.create(title=data['title'],
gender=data['gender'],
first_name=data['first_name'],
surname=data['surname'],
dob=data['dob'],
notes=data['notes'],
medical=data['medical'],
content_object=cust,
)
cust.save()
address = Address.objects.create(address=data['address'],
city=data['city'],
county=data['county'],
postcode =data['postcode'],
country=data['country'],
content_object=address,
)
address.save()
email = Email.objects.create(email=data['email'],
content_object=email)
email.save()
phone = Phone.objects.create(number=data['phone'],
content_object=phone)
phone.save()
Just call the code for creation of the course object after creating the customer object.
The issue is, the ForeignKey customer in Course model is required, and you have not set that field while creating the object.
You have a couple of other minor issues which I have fixed in the code. .
def save(self):
data = self.cleaned_data
course_booking = None
if self.cleaned_data['course']:
crs = self.cleaned_data['course']
course_booking = CourseBooking(course=crs)
course_booking.save()
cust = Customer.objects.create(title=data['title'],
gender=data['gender'],
first_name=data['first_name'],
surname=data['surname'],
dob=data['dob'],
notes=data['notes'],
medical=data['medical'],
content_object=cust,
)
#cust.save()
course = CourseBooking.objects.create(course=data['course'], customer = cust)
if course_booking:
course.booking = course_booking
#course.save()
address = Address.objects.create(address=data['address'],
city=data['city'],
county=data['county'],
postcode =data['postcode'],
country=data['country'],
content_object=address,
)
#address.save()
email = Email.objects.create(email=data['email'],
content_object=email)
#email.save()
phone = Phone.objects.create(number=data['phone'],
content_object=phone)
#phone.save()
On another note, I would put this object creation logic in the view, rather than the model_form's save method.