Djnago Form getting Error while edit record - django

I am getting Issue while edit a record based on CHatquestion ID, if option is null then i need to add a record based on same chatquestion id, if chatqustion id exist in option it will work,
i am trying to multiple way to solve this issue but still can't find solution.
Models.py # thease are all 3 models
class Problem(models.Model):
Language = models.IntegerField(choices=Language_CHOICE, default=1)
type = models.CharField(max_length=500, null=True, blank=True)
def __str__(self):
return self.type
class ChatQuestion(models.Model): # Eding record based on chatquestion id
question = RichTextField(null=True, blank=True)
problem_id = models.ForeignKey(
Problem,
models.CASCADE,
verbose_name='Problem',
)
def __str__(self):
return self.question
is_first_question = models.BooleanField(default=False)
class Option(models.Model):
option_type = models.CharField(max_length=250, null=True, blank=True)
question_id = models.ForeignKey(
ChatQuestion,
models.CASCADE,
verbose_name='Question',
null=True,
blank=True
)
problem=models.ForeignKey(
Problem,
models.CASCADE,
verbose_name='Problem',
null=True,
blank=True
)
next_question_id = models.ForeignKey(ChatQuestion, on_delete=models.CASCADE, null=True, blank=True,
related_name='next_question')
def __str__(self):
return self.option_type
forms.py
class EditQuestionForm(forms.ModelForm):
class Meta:
model = ChatQuestion
fields =('question','problem_id')
class EditOptionForm(forms.ModelForm):
class Meta:
model = Option
fields =('option_type',)
views.py
def question_edit(request,id=None):
if id is not None:
queryset = get_object_or_404(ChatQuestion,pk=id)
queryset1=get_object_or_404(Option,question_id=queryset )
else:
queryset = None
queryset1 = None
if request.method=="POST":
form = EditQuestionForm(request.POST ,instance=queryset)
form1=EditOptionForm(request.POST, instance=queryset1)
if form.is_valid() and form1.is_valid():
question=form.cleaned_data['question']
option_type=form1.cleaned_data['option_type']
if id:
queryset.question=question
queryset.save()
queryset1.option_type=option_type
queryset1.save()
messages.success(request,'Sucessful')
return redirect('/fleet/list_chatbot')
else:
print(form.errors)
messages.error(request,'Please correct following',form.errors)
elif id:
form = EditQuestionForm(instance=queryset)
form1=EditOptionForm(instance=queryset1)
if not queryset1:
form1=EditOptionForm()
else:
form = EditQuestionForm()
form1=EditOptionForm()
context={
'form':form,
'form1':form1
}
return render(request,'chatbot/question_edit.html',context=context)

Related

Autofilling Django model form field with data from associated objects

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)

foreign key in django

I have a model for musics and a model for comment of musics:
class music(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
STATUS_CHOICES = (('draft', 'Draft'), ('published', 'Published'),)
music = models.FileField()
music_image = models.ImageField(upload_to="images/")
singer_name = models.CharField(max_length=100)
music_name = models.CharField(max_length=100)
text_of_music = models.TextField()
create = models.DateField(auto_now_add=True, blank=True, null=True)
update = models.DateField(auto_now=True, blank=True, null=True)
publish = models.DateField(default=timezone.now, blank=True, null=True)
slug = models.CharField(max_length=250, unique_for_date='publish')
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
objects = models.Manager()
published = PublishedManager()
class Meta:
ordering = ('-publish',)
def get_absolute_url(self):
return reverse('music:music_detail',
kwargs={"id":self.id})
class comment(models.Model):
# Foreignkey for each music
For = models.ForeignKey(music, on_delete=models.CASCADE, related_name='post')
body = models.CharField(max_length=500)
created_on = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=True)
commented_by = models.ForeignKey(User, on_delete=models.CASCADE)
and this is my view:
def music_Detail(request, id=None):
user = request.user
template_name = 'music/music_detail.html'
Music = music.objects.all().filter(id=id)
new_comment = None
Comment = comment.objects.all().filter(active=True)
form = comment_form(data=request.POST)
if request.method == 'POST':
if form.is_valid():
new_comment = form.save(commit=False)
new_comment.For = Music
new_comment.save()
form = comment_form()
return render(request, template_name, {'Music': Music, 'Comment': Comment, 'form': form})
Well, I get this error when I comment:
Cannot assign "<QuerySet [<music: m, majid kharatha>]>": "comment.For" must be a "music" instance.
How can I solve this problem and how can I display the information of the user who left this comment?
As the error says, you'll have to assign a single Music, not a queryset.
Instead of filter()ing to get a new queryset containing a single music,
Music = music.objects.all().filter(id=id)
you want to get() a single one:
Music = music.objects.get(id=id)

Custom "business" logic using pure Django

I am set on building a small website using django. What i am trying to do right now is using a CreateView based on a Model "Order", which one of its fields is another model "Customer".
The form itself works to create Orders, but im trying to find out how i can validate that the Customer that was selected is "enabled" (there is a status in the Customer model).
I was trying using the clean method but it doesnt even seem to be executing. I tried just raising the error on the clean, without validating anything, and still doesnt work. Any clue what might be wrong?
My Form:
class OrderForm(ModelForm):
def clean_customer(self, *args, **kwargs):
raise forms.ValidationError("This customer is banned.")
class Meta:
model = Order
fields = '__all__'
Relevant Models:
class Order(models.Model):
ORDER_STATUS = (('Pending Delivery', 'Pending Delivery'),
('Book on Customer', 'Book on Customer'),
('Overdue', 'Overdue'),
('Completed','Completed'))
customer = models.ForeignKey(Customer, null=True, on_delete=models.SET_NULL)
book = models.ForeignKey(Book, null=True, on_delete=models.SET_NULL)
date_created = models.DateTimeField(auto_now_add=True)
date_due = models.DateTimeField(null=True)
date_completed = models.DateTimeField(null=True, blank=True)
status = models.CharField(max_length=100, choices=ORDER_STATUS, null=True)
def get_absolute_url(self):
return reverse('orders')
class Customer(models.Model):
status = models.CharField(max_length=10, null = True, choices=STATUS_CHOICES)
name = models.CharField(max_length=200, null=True)
username = models.CharField(max_length=25, null = True)
email = models.EmailField(null=True)
def __str__(self):
return str(self.name)+" - " +str(self.username)
def get_absolute_url(self):
return reverse('customers')
The View:
class OrderCreateView(CreateView):
model = Order
fields = '__all__'
def form_valid(self, form):
return super().form_valid(form)

How to load an instance in class based views using form_valid

I'm trying to build a form that automatically fills some fields in a class based create view that lets logged in users create a Job. However, I can't seem to find the correct way of doing this for fields that aren't the user (eg. request.user).
So the create view is trying to get a company_name from the logged in user, company_name field belongs to a model called Company. Each Company has an owner with a foreign key to the User model. All the reuest I've tried so far have led to a 'WSGIRequest' error.
So far I've tried to request:
company_name
user.company_name
company.company_name
company
user
I don't understand how these requests work, I have seen examples for getting the logged in users name and I'm not familiar how to do this otherwise.
Please can someone help me understand how this works and how I should be doing this?
I'm using Django 2.2 with python 3.6
Auth Models:
class User(AbstractBaseUser, PermissionsMixin):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
phone_number = models.CharField(max_length=15)
email = models.EmailField(max_length=250, unique=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
objects = UserManager()
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
def __str__(self):
return self.first_name
def get_absolute_url(self):
return "/users/%i/" % self.pk
class Company(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
company_name = models.CharField(max_length=100, unique=True)
company_address = models.CharField(max_length=100, unique=True)
company_website = models.URLField(blank=True, null=True)
company_verified = models.BooleanField(default=False)
def __str__(self):
return self.company_name
View
class JobCreateView(LoginRequiredMixin, CreateView):
model = Job
form_class = JobForm
template_name = 'jobs/job_create.html'
def form_valid(self, form):
form.instance.company_name = self.request.user
form.instance.job_reference = self.request.job.pk
return super(JobCreateView, self).form_valid(form)
def get_success_url(self):
return reverse('jobs:job_details', kwargs={'pk': self.object.pk})
Other Model:
class Job(models.Model):
JOB_TYPE = (
('1', 'Service'),
('2', 'Repair'),
('3', 'Quotation'),
('4', 'Consultation'),
('5', 'Report'),
('6', 'Design'),
)
ACCOUNT_TYPE = (
('1', 'Existing Customer'),
('2', 'Charge to Account'),
('3', 'New Customer'),
('4', 'Pre-Paid/C.O.D'),
('5', 'Issued and Acc App'),
)
company_name = models.ForeignKey(Company, related_name='jobs', verbose_name="Company Name", on_delete=models.CASCADE)
job_reference = models.CharField(max_length=50, blank=False)
contact_person = models.CharField(max_length=50)
contact_number = models.IntegerField()
contact_person_email = models.EmailField(max_length=100, blank=True, null=True)
site_address = models.CharField(max_length=100)
job_type = models.CharField(choices=JOB_TYPE, max_length=50, default='1')
account_type = models.CharField(choices=ACCOUNT_TYPE, max_length=50, default='1')
job_details = models.CharField(max_length=1000)
created = models.DateTimeField(default=now, blank=True)
def __str__(self):
return str(self.company_name)
def get_absolute_url(self):
return reverse('jobs:detail', kwargs={'pk': self.pk})
For anyone trying to solve a problem like this, the answer is;
Views:
class JobDocketCreate(CreateView):
model = JobDocket
form_class = JobDocketForm
template_name = 'jobs/job_docket_create.html'
def form_valid(self, form):
form.instance.technician = self.request.user
form.instance.job = Job.objects.get(pk=self.kwargs['job_pk'])
print(form.instance.job)
print(form.instance.technician)
context = {'job_pk':self.kwargs['job_pk']}
return super(JobDocketCreate, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(JobDocketCreate, self).get_context_data(**kwargs)
context['job_pk'] = self.kwargs['job_pk']
return context
def get_success_url(self):
return reverse('jobs:my_job_dockets')
Form action in View:
action="{% url 'jobs:create_job_docket' job_pk %}"

Save the Logged in User to the database model on form submission with django 1.8

I have a model and I am trying to save the user to the models database when the user submits the form. I had a site that did this but now my editor says "Use of super on an old style class"
I am using django 1.8 and i get
IntegrityError at /auction/createview/ NOT NULL constraint failed:
auction_auction.user_id
which is the nicest error I have been able to get. with all the tinkering i have done
class AuctionCreateView(LoginRequiredMixin,CreateView):
model = Auction
action = "created"
form_class = AuctionForm
auction_form = AuctionForm(initial={'user':request.user})
class AuctionForm(forms.ModelForm):
class Meta:
model = Auction
fields = (
"user",
"item_name",
"reserve",
"start_date",
"end_date",
"description",
"tags",
)
class Auction(models.Model):
user = models.ForeignKey(User)
item_id = models.CharField(max_length=255, blank=True, null=True)
item_name = models.CharField(max_length=255, blank=True, null=True)
winner = models.ForeignKey(User, related_name='Auction_Winner', blank=True, null=True)
reserve = MoneyField(max_digits=10, decimal_places=2, default_currency='USD')
created = models.DateTimeField(editable=False, null=True)
slug = AutoSlugField(('slug'), max_length=128, unique=True, populate_from=('item_name',))
start_date = models.DateTimeField(verbose_name="Start date")
end_date = models.DateTimeField(verbose_name="End date")
active = models.BooleanField(default=False, verbose_name='Active')
total_bids = models.IntegerField(default=0, verbose_name='Total bids')
date_added = models.DateTimeField(auto_now_add=True, verbose_name='Date added')
last_modified = models.DateTimeField(auto_now=True, verbose_name='Last modified')
description = models.TextField(max_length=3000)
tags = tagging.fields.TagField()
# bid_set = models.IntegerField(default= 0, verbose_name = "Bid set")
starting_amount = MoneyField(max_digits=10, decimal_places=2, default_currency='USD')
def __unicode__(self):
return '%s selling %s' % (self.user, self.item_name)
def _get_increment(self):
""" add some logic to base incrementing amount on starting price """
def get_absolute_url(self):
return reverse('auction_detail',
kwargs={'slug': self.slug})
when i saw this post I thought i'd be able to figure it out. thanks  ★ ✩
You need insert user_id before form save.
AuctionForm - need update request.user value. Added this fields from form initial.
You have to include 'user' on the fields of the Auction form class to solve that error and just put an initial parameter on the form instance in the views.py like
auction_form = AuctionForm(initial={'user':request.user})
because request.user on the form_valid method will not work at all