How to use stored_procedure on Django Rest_framework - django

I'am trying to use my own stored_procedure to create an API of my own, it's purpose is to add an item into a table
this is my raw Models.py
class Clearanceinsert(models.Model):
sem = models.CharField(max_length=1, blank=True, null=True)
sy = models.CharField(max_length=9, blank=True, null=True)
this is currently my insert function
def add(request):
if request.method == "POST":
if request.POST.get('sem') and request.POST.get('sy')
saverec = Clearanceinsert()
saverec.sem = request.POST.get('sem')
saverec.sy = request.POST.get('sy')
cursor = connection.cursor()
userid = request.user.userid
cursor.execute("select add_clearance_item_new('"+saverec.sem+"','"+saverec.sy+"')
return HttpResponseRedirect('/Admin/index')
else:
return render(request, 'Admin/add.html')
I did create an serializer
class InsertItemSerialize(serializers.ModelSerializer):
Class Meta:
fields = ['sem','sy']
I remove some column so the code is shorter and easy to read, but this is basically it

Related

How to display conditional form field that is dependent on an attribute of a selected foreign key on django model form

I want to conditionally display either frequency_input or duration_input fields based on the behavior.recording attribute of the selected behavior.
I have a Trial form that currently displays 3 fields:
behavior_name (foreign Key) dropdown
frequency_input
duration_input
Im not sure if i should the best method to solve this (Javascript or solve in the View)?
Trial Model
class Trial(models.Model):
behavior_name = models.ForeignKey(Behavior, on_delete=models.CASCADE)
client_session = models.ForeignKey(Client_Session, on_delete=models.CASCADE)
frequency_input = models.PositiveIntegerField(default=0, blank=True)
duration_input = models.DurationField(blank=True, default=timedelta(minutes=0))
class Meta:
verbose_name_plural = 'trials'
def __str__(self):
return str(self.id)
Behavior Model
RECORDING_CHOICES = (
('Rate','RATE'),
('Duration','DURATION'),
('Frequency','FREQUENCY')
)
class Behavior(models.Model):
name = models.CharField(max_length=200)
goal = models.CharField(max_length=200)
recording = models.CharField(max_length=10, choices=RECORDING_CHOICES, null=False)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='Active')
def __str__(self):
return self.name
Trial Form
class TrialForm(forms.ModelForm):
class Meta:
model = Trial
fields = ('behavior_name','frequency_input', 'duration_input')
Add Trial View
def add_trial(request, clientsession_id):
client_session = Client_Session.objects.get(id=clientsession_id)
if request.method != 'POST':
form = TrialForm()
else:
form = TrialForm(data=request.POST)
if form.is_valid():
add_trial = form.save(commit=False)
add_trial.client_session = client_session
add_trial.save()
return HttpResponse(status=204, headers={'HX-Trigger': 'trialupdated'})
context = {'client_session': client_session, 'form': form}
return render(request, 'sessions/add_trial.html', context)

Passing parent object into CreateView for a child object

I'm creating a dashboard to edit a tour app.
Per tour I have a child record in which I define steps. The 2 models look like this:
models.py
class Tour(models.Model):
tour_id = models.CharField(primary_key=True,unique=True, max_length=10)
country = models.ForeignKey(Countries, models.DO_NOTHING, db_column='country')
language = models.ForeignKey(Language, models.DO_NOTHING, db_column='language')
lastupddtm = models.DateTimeField(default=timezone.now)
productid = models.CharField(max_length=50)
title = models.CharField(max_length=50)
description = models.CharField(max_length=100)
descrlong = models.CharField(max_length=1000)
live = models.CharField(max_length=1)
image = models.ImageField(upload_to=upload_tour_image, storage=OverwriteStorage(), blank=True, null=True)
class Meta:
db_table = 'tour'
verbose_name_plural = "tour"
def get_language_flag(self):
return self.language.flag.url
def __str__(self):
return str(self.tour_id) + ' - ' + str(self.title) + ' - ' + str(self.description)
class Toursteps(models.Model):
# tour_id = models.OneToOneField(Tour, models.DO_NOTHING, db_column='tour_id')
tour = models.ForeignKey(Tour, related_name='toursteps', on_delete=models.CASCADE)
step = models.IntegerField(unique=True)
title = models.CharField(max_length=50)
description = models.CharField(max_length=100)
descrlong = models.CharField(max_length=1000)
audiotext = models.TextField()
latitude = models.FloatField()
longitude = models.FloatField()
radius = models.FloatField()
image = models.ImageField(upload_to=upload_tour_step_image, blank=True, null=True)
class Meta:
db_table = 'tourSteps'
verbose_name_plural = "tourSteps"
def __str__(self):
return str(self.tour) + "|" + str(self.step)
After I created a Tour, I go to a detail page. From there I can click a link to add a step for this tour.
This is where the problem is. I pass the tour_id as a variable into the url, but I can't find a way to pick it up in the CreateView of the step.
urls.py
urlpatterns = [
path('tour/<str:pk>/detail', views.TourDetailView.as_view(), name='tour_detail'),
path('tour/<str:pk>/edit', views.UpdateTourView.as_view(), name='tour_edit'),
path('tour/<str:pk>/remove', views.DeleteTourView.as_view(), name='tour_remove'),
path('tour/<str:tour_id>/step/new', views.CreateTourStepView.as_view(), name='tour_step_new')
]
Tour detail view
<p><span class="glyphicon glyphicon-plus"></span></p>
views.py
class CreateTourStepView(LoginRequiredMixin,CreateView):
login_url = '/login/'
redirect_field_name = 'tour_admin/tour_list.html'
success_url = '/'
form_class = TourStepForm
model = Toursteps
def get_context_data(self, **kwargs):
context = super(CreateTourStepView, self).get_context_data(**kwargs)
print(context['tour_id'])
return context
forms.py
class TourStepForm(forms.ModelForm):
class Meta():
model = Toursteps
#fields = '__all__'
exclude = ('tour',)
def form_valid(self, form):
if form.is_valid():
form.instance.tour_id = self.request.GET("tour_id")
form.instance.save()
return HttpResponseRedirect(self.get_success_url())
def get_success_url(self):
return reverse('tour_detail', kwargs={'pk':form.instance.tour_id})
First, your form_valid() and get_success_url() methods belong in your view, not in your form.
Second, the tour_id is passed to the view's kwargs, it's not a query parameter, hence not in self.request.GET. You can find it in self.kwargs.
Third, you need to actually fetch the Tour from your database, not just assign the tour_id. I could post to any tour_id if I wanted and there's no guarantee the tour_id belongs to an actual Tour object. Return a 404 if the tour doesn't exist. And if it exists, assign it to the tour step.
Finally, you should not assign to and save form.instance. You should get the instance using step = form.save(commit=False), then assign to step and save step.

Django Forms CheckboxInput on Y/N String field in existing database

I'm relatively new to Django, and I'm making a form which I'm connecting to a existing MySQL database.
What I'm trying to do is create a maintenance page for countries. One of the fields in my database is eu_member_state.
What I'm trying to do here is create a checkbox for this field, so I can uncheck it for the United Kingdom which recently got out of the EU.
class CountryForm(forms.ModelForm):
class Meta():
model = Countries
fields = '__all__'
widgets = {
'eu_member_state': forms.CheckboxInput()
}
The checkbox does appear on my form, but how can I make this talk to my database? How can this checkbox only be checked when the database value is 'Y', and how do I write this back to my database on save, so 'Y' when checked and 'N' when unchecked?
This is the model code:
from django.db import models
class Countries(models.Model):
country = models.CharField(unique=True, max_length=3)
descr = models.CharField(max_length=50, blank=True, null=True)
descrshort = models.CharField(max_length=20, blank=True, null=True)
country_2char = models.CharField(max_length=2, blank=True, null=True)
eu_member_state = models.CharField(max_length=1, blank=False, null=False, default='N')
class Meta:
db_table = 'countries'
verbose_name_plural = "countries"
def __str__(self):
return self.descr
I managed to work around it by creating a custom CheckboxInput field and initialise this in the forms.py.
class CountryForm(forms.ModelForm):
eu_member_state_flag = forms.BooleanField(required=False,label='EU member state')
class Meta():
model = Countries
exclude = ('eu_member_state',)
def __init__(self, *args, **kwargs):
super(CountryForm, self).__init__(*args, **kwargs)
if self.instance.eu_member_state == "Y":
flag_value = True
else:
flag_value = False
self.initial['eu_member_state_flag'] = flag_value
Then in views.py I'm fetching the value of the CheckboxInput field and convert that into a 'Y' or a 'N'.
class UpdateCountryView(LoginRequiredMixin,UpdateView):
login_url= '/login/'
redirect_field_name = 'tour_admin/countries_list.html'
form_class = CountryForm
model = Countries
def form_valid(self, form):
if form.is_valid():
data = form.cleaned_data
if data['eu_member_state_flag']:
data['eu_member_state'] = 'Y'
self.object.eu_member_state = 'Y'
else:
data['eu_member_state'] = 'N'
self.object.eu_member_state = 'N'
self.object.save()
return HttpResponseRedirect(self.get_success_url())
def get_success_url(self):
return reverse('countries_list')

How to update two models with one form?

I want to be able to have a user update two models with one submit button. The first model will house all of the book titles (unique) and pages that users submit. The other will show which users submitted which books.
Ideally, I'd like to do something like this:
if request.method == "POST":
form = AddBookForm(request.POST)
if form.is_valid():
books = form.save(commit=False)
ub = UserBooks()
books.book_title = form.cleaned_data['book_title']
books.book_total_pages = form.cleaned_data['book_total_pages']
ub.user = request.user
ub.book_title = form.cleaned_data['book_title']
ub.save()
books.save()
return redirect('new_book')
But that's giving me the error:
Cannot assign "'Some Book Title'": "UserBooks.book_title" must be a
"Books" instance.
What would be the best way to update two models with one form?
Here are the other files.
models.py
class Books(models.Model):
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
book_title = models.CharField(max_length=100, unique=True)
book_total_pages = models.IntegerField()
class Meta:
ordering = ('-created',)
def __str__(self):
return '{0}'.format(self.book_title)
class UserBooks(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=False, blank=False)
book_title = models.ForeignKey(Books, on_delete=models.CASCADE, null=False, blank=False)
views.py
def new_book(request):
user = request.user
if request.method == "POST":
form = AddBookForm(request.POST)
if form.is_valid():
books = form.save(commit=False)
books.book_title = form.cleaned_data['book_title']
books.book_total_pages = form.cleaned_data['book_total_pages']
books.save()
return redirect('new_book')
else:
form = AddBookForm()
return render(request, 'main/addanewbook.html', {
'form': form,
'allBooks': allBooks,
'userbooks': userbooks,
})
forms.py
class AddBookForm(forms.ModelForm):
class Meta:
model = Books
fields = ('book_title', 'book_total_pages')
you need to change a bit in the view
if form.is_valid():
books = form.save(commit=False)
ub = UserBooks()
books.book_title = form.cleaned_data['book_title']
books.book_total_pages = form.cleaned_data['book_total_pages']
books = books.save()
ub.user = request.user
ub.book_title = books
ub.save()
return redirect('new_book')
this will do it

How do I map one models objects to another models objects in a view

I have a bunch of message records that I would like to assign to different taskboxes.
#models.py
class TaskBox(models.Model):
name = models.CharField(max_length=64, blank=False)
def __str__(self):
return u'%s' % (self.name)
class Admin:
pass
class InboxEntry(models.Model):
job_number = models.CharField(max_length=14, unique=False, blank=False, null=False)
job_name = models.CharField(max_length=64, unique=False, blank=False, null=False)
request = models.CharField(max_length=64, choices=PRINT_CHOICES, blank=True, null=True)
date_due = models.DateTimeField(("Due"),auto_now=False)
note = models.TextField(max_length=1000, unique=False, blank=True, null=True)
assigned_by = models.ForeignKey(UserProfile, blank=False, null=False)
box = models.ForeignKey(TaskBox)
assigned_to = models.ManyToManyField(UserProfile, related_name='name', blank=True)
status = models.CharField(max_length=30, choices=STATUS_CHOICES, default="Awaiting Action")
def __str__(self):
return u'%s %s' % (self.job_number, self.job_name)
class Admin:
pass
class Meta:
ordering = ['status']
The idea is for the template to have some generic tags like {{ for taskbox in taskboxes }} to create a separate div for each taskbox that will hold a table for that box's records. My problem is constructing the view function...
#views.py
def display_prdInboxEntry(request, id):
if request.method == 'POST':
form = PrdInboxForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('taskmanager/display/'+ id +'/')
else:
form = PrdInboxForm(request.POST)
return HttpResponseRedirect('taskmanager/display/'+ id +'/')
else:
form = PrdInboxForm()
user = request.user
**taskboxes = TaskBox.objects.all()
records_1 = InboxEntry.objects.filter(taskboxes[id]=1)
records_2 = InboxEntry.objects.filter(taskboxes[id]=2)
records_3 = InboxEntry.objects.filter(taskboxes[id]=3)
..... **
return render_to_response('taskmanager/taskmanager_view.html', {'form': form, 'taskboxes': taskboxes, 'records_1' : records_1, 'records_2' : records_2, 'records_3' : records_3, 'user': user}, context_instance=RequestContext(request))
The InboxEntry model has a field called "box" that's just a reference to the TaskBox model. I need a way to map say... TaskBox id 1 with all of the InboxEntry objects with "box = 1" so that I can populate the templates appropriately. Can I construct the function to accommodate this, or am I going about it the wrong way entirely?
It sounds like you're looking for the automatically-generated attribute for reverse lookups. You can get a QuerySet of all InboxEntries associated with a TaskBox like this:
TaskBox.objects.filter(id=1).inboxentry_set.all()
See the documentation on related objects.