I have a form that submits data, but before submitting to the database it will take the value from foreign first.
here my models.py
class Employee(models.Model):
nik = models.CharField(max_length=100)
name = models.CharField(max_length=100)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("system:detail",kwargs={'pk':self.pk})
class EmpLoan(models.Model):
status = models.BooleanField()
nominal = models.DecimalField(max_digits=10, decimal_places=0)
emp = models.ForeignKey(Employee, related_name='emploan')
created_at = models.DateTimeField(auto_now=True)
updated_at = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return self.emp.name
class EmpInstallment(models.Model):
nominal = models.DecimalField(max_digits=10, decimal_places=0)
loan = models.ForeignKey(EmpLoan, related_name='empinstallment')
created_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.loan.emp.name
view.py
class EmployeeCreateView(CreateView):
fields = ()
model = models.Employee
def form_valid(self, form):
self.object = form.save(commit=False)
data = self.object.EmpLoan.EmpInstallment.object.get(id=1)
self.object.nik = data
self.object.save()
return super(ModelFormMixin, self).form_valid(form)
how to access data on EmpInstallment?...
iam trying use this data = self.object.EmpLoan.EmpInstallment.object.get(id=1)
but it's not working.
iam still learner and very noob on django
EmpInstallment -- > ForeignKey to ---> EmpLoan -----> ForeignKey to ---Employee
class EmployeeCreateView(CreateView):
fields = ()
model = models.Employee
def form_valid(self, form):
employee_instance = form.save(commit=False)
# try to get the emploan instance
emploan = employee_instance.emploan.first()
if emploan:
empinstallment = emploan.empinstallment.first()
if empinstallment:
pass # there you can execute your codes
# there you have access to empinstallment
Related
I have created a form named as AttendanceForm :
class AttendanceForm(forms.ModelForm):
class Meta:
model = Attendance
fields = '__all__'
These are models
class Employee(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
eid = models.IntegerField(primary_key=True)
salary = models.IntegerField()
gender = models.CharField(max_length=6, choices=GENDER_CHOICES, default=1)
contactno = models.CharField(max_length=10)
email = models.CharField(max_length=30)
country = models.CharField(max_length=30)
city = models.CharField(max_length=20)
pincode = models.IntegerField()
address = models.CharField(max_length=60)
def __str__(self):
return self.user.first_name + ' ' + self.user.last_name
class Attendance(models.Model):
employee = models.ForeignKey(Employee, on_delete=models.CASCADE, default=1)
attendancedate = models.DateField()
in_time = models.TimeField()
out_time = models.TimeField()
description = models.TextField()
def __str__(self):
return str(self.employee)
view for attendance.
#csrf_exempt
def addattendance(request):
form = AttendanceForm()
emp_list = Employee.objects.all()
if request.method == 'POST':
form = AttendanceForm(request.POST)
if form.is_valid():
form.save(commit=True)
return redirect('employee/detail_attendance')
return render(request, 'employee/addattendance.html', {'form': form, 'emp_list': emp_list})
I tried everything, but I don't know why the data is not saving into the database. Also, models are created fine, and the main thing is that there are no errors coming up.
Please let me know if any changes are required.
I can suggest simple solution with Class-Based-Views:
from django.views.generic.edit import FormView
def AddAttendanceFormView(FormView):
form_class = AttendanceForm
extra_context = {"emp_list": Employee.objects.all()}
success_url = reverse_lazy('employee/detail_attendance')
template_name = 'employee/addattendance.html'
def post(self, *args, **kwargs):
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
return self.form_invalid(form)
Remember, that in urls.py you need to use .as_view() for class based views, like:
path((...), AddAttendanceFormView.as_view())
Also, you will not need #csrf_exempt, just put {% csrf_token %} anywhere inside your form's template.
I tried several ways to solve the problem but I couldn't .. every time I got it error. Item added to DB but error message returned on page.
why "get_absolute_url" and "success_url" do not work?
View
class AddItemView(CreateView):
model = Add_Item
form_class = AddItemForm
template_name ='add_item.html'
success_url = reverse_lazy("home")
def form_valid(self, form):
self.object = form.save(commit=False)
# Add_Item.User = User
self.object.user = self.request.user
self.object.save()
Models
class Add_Item(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE, default=None,
null=True)
title = models.CharField(max_length=255)
categories = models.CharField(max_length=255 , choices=all_categories)
description = RichTextField(blank=True,null=True)
condition = models.CharField(max_length=100, choices=cond)
city = models.CharField(max_length=50, choices=cy.city, blank=True)
street = models.CharField(max_length=100, blank=True)
home_number = models.CharField(max_length=100, blank=True)
header_img = models.ImageField(null=True, blank=True, upload_to='img/')
more_img = models.ImageField(null=True, blank=True, upload_to='img/')
Pub_date = models.DateField(auto_now_add=True)
def __str__(self):
return str(self.title)
def get_absolute_url(self):
return reverse('home')
From the docs:
def form_valid(self, form):
# This method is called when valid form data has been POSTed.
# It should return an HttpResponse.
return super().form_valid(form)
You need to add the return line.
I have a model form that creates a new job entry, and on submission, I need an invisible field job_time_estimation to be set to a sum of 'service_stats_estimate_duration' values from ServiceItemStats objects associated with the JobEntry by a many-to-many relationship when submitting the form.
For example, if in my NewJobEntryForm I chose two existing ServiceItemStats objects that have service_stats_estimate_duration values 60 and 90, on submission, I want a value 150 to be saved in that JobEntry object's job_time_estimation attribute.
I tried doing this using aggregation by defining a save() method in the model but I am getting an error "name 'serviceItemStats' is not defined".
I am not sure if I am going about this the right way. Any help would be appreciated.
My code:
models.py:
class ServiceItemStats(models.Model):
service_stats_name = models.CharField(primary_key=True, max_length=20)
service_stats_estimate_duration = models.IntegerField()
# Many-to-many relationship with JobEntry.
def __str__(self):
return self.service_stats_name
class JobEntry(models.Model):
# PK: id - automatically assigned by Django.
jo
b_entry_date_time = models.DateTimeField(default=timezone.now)
jo
b_date = models.DateField(blank=True, null=True)
job_checked_in = models.BooleanField()
job_checked_out = models.BooleanField(default=False)
job_priority = models.IntegerField()
job_time_estimation = models.IntegerField(blank=True, null=True)
job_comments = models.TextField(max_length=200, blank=True, null=True)
job_parts_instock = models.BooleanField(default=False)
job_started = models.BooleanField(default=False)
job_finished = models.BooleanField(default=False)
job_expand_fault_evidence = models.ImageField(blank=True, null=True)
job_expand_comments = models.ImageField(blank=True, null=True)
job_expand_parts_required = models.CharField(max_length=200, blank=True, null=True)
vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE) #One-to-one relationship
customer = models.ForeignKey(Customer, on_delete=models.CASCADE) #One-to-one relationship
serviceBay = models.ForeignKey(ServiceBay, on_delete=models.CASCADE, blank=True, null=True) #One-to-one relationship
serviceItemStats = models.ManyToManyField(ServiceItemStats, blank=True) #Many-to-many relationship
def __str__(self):
return self.id
def save(self, *args, **kwargs):
if not self.job_time_estimation:
self.job_time_estimation = serviceItemStats.objects.all().aggregate('service_stats_estimate_duration')
return super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse("jobs:job_detail",kwargs={'pk':self.pk})
views.py
class JobCreateView(FormView):
template_name = "jobs/jobentry_form.html"
form_class = NewJobEntryForm
success_url = reverse_lazy("jobs:job_list")
def form_valid(self, form):
form.save()
return super(job_list, self).form_valid(form)
forms.py
class NewJobEntryForm(ModelForm):
class Meta:
model = JobEntry
fields = ['vehicle', 'customer', 'job_date', 'job_checked_in', 'job_priority', 'job_comments', 'job_parts_instock', 'serviceItemStats']
widgets = {
'job_date' : forms.DateInput(format=('%m/%d/%Y'), attrs={'class':'form-control', 'placeholder':'Select a date', 'type':'date'}),
'ServiceItemStats' : forms.CheckboxSelectMultiple(),
'job_priority' : forms.RadioSelect(choices=priorityOptions),
}
You can try this.
from django.db.models import Sum
class JobCreateView(FormView):
template_name = "jobs/jobentry_form.html"
form_class = NewJobEntryForm
success_url = reverse_lazy("jobs:job_list")
def form_valid(self, form):
job=form.save()
estimation = job.serviceItemStats.all().aggregate(total=Sum('service_stats_estimate_duration'))
job.job_time_estimation = estimation['total']
job.save()
return super(job_list, self).form_valid(form)
I am creating a wiki and need to put in values in the model called revision. This table has a foreigkey to wikipage.
My problem is that I am unable to insert values in the revision model.
I have tried using def form_valid(self, form) like you would when entering user, without any luck.
Models.py
class Wikipage(models.Model):
title = models.CharField(max_length=100)
date_created = models.DateTimeField('Created', auto_now_add=True)
def __str__(self):
return self.title
class Meta:
verbose_name_plural = "Wikipages"
class Revision(models.Model):
wikipage = models.ForeignKey(Wikipage, null=True, on_delete=models.CASCADE, related_name='revisions')
content = models.TextField('Content')
author = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
last_edit = models.DateTimeField('Last Edited', auto_now=True)
comment = models.TextField('Comment', blank=True)
class Meta:
verbose_name = 'Revision'
verbose_name_plural = 'Revisions'
ordering = ['-last_edit']
get_latest_by = ['last_edit']
def __str__(self):
return self.content
View.py
Class WikipageCreateView(CreateView):
template_name = 'wiki/wikipageform.html'
model = Wikipage
fields = ['title']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
The template are as simple as possible with {{ form.as_p }} and all the necessary stuff.
I have created 'post' model in which I included 'post_id' as the primary key field. When I am trying to create a post, it is raising an error: 'badly formed hexadecimal UUID string'. I would appreciate helping me in solve this.
Here's my code.
Models.py:
class Post(models.Model):
post_id = models.UUIDField(primary_key=True, default='uuid.uuid4', editable=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
from1 = models.CharField(max_length=20)
To = models.CharField(max_length=20)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
objects = PostManager()
def __unicode__(self):
return self.post_id
def __str__(self):
return self.post_id
def get_absolute_url(self):
return reverse("posts:detail", kwargs={"post_id": self.post_id})
class Meta:
ordering = ["-timestamp", "-Time"]
views.py:
def post_create(request):
form = PostForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
print(form.cleaned_data.get("post_id"))
instance.user = request.user
instance.save()
return HttpResponseRedirect(instance.get_absolute_url())
context = {
"form": form,
}
return render(request, "loggedin_load/post_load.html", context)
I would do something like this:
from django.utils.encoding import python_2_unicode_compatible
#python_2_unicode_compatible
class Post(models.Model):
# Instead of default, maybe do null=True to take old entries into account?
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
from1 = models.CharField(max_length=20)
# You may want to reconsider the naming of the "To" field
# to avoid capital letters and built-in functions
To = models.CharField(max_length=20)
timestamp = models.DateTimeField(auto_now_add=True)
objects = PostManager()
# You can remove this with the decorator above
# def __unicode__(self):
# return self.id
def __str__(self):
return self.id # acts as your post_id
def get_absolute_url(self):
return reverse("posts:detail", kwargs={"post_id": self.id})
class Meta:
ordering = ["-timestamp", "-Time"]
Whenever an object is created, it will automatically be assigned an id, which will populate your __unicode__, __str__, and get_absolute_url.
You need to import the module and not use quotes around 'uuid.uuid4'.
It should be somewhat like:
import uuid # The uuid module
class Post(models.Model):
post_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) # using the function uuid4 on the module
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
from1 = models.CharField(max_length=20)
To = models.CharField(max_length=20)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
objects = PostManager()
def __unicode__(self):
return self.post_id
def __str__(self):
return self.post_id
def get_absolute_url(self):
return reverse("posts:detail", kwargs={"post_id": self.post_id})
class Meta:
ordering = ["-timestamp", "-Time"]
N.B I've not tested the above code, and I agree with some of the comments you shouldn't need a UUID for the post_id. Without knowing more I couldn't help further.