I am building an application that allows a user to create a scenario, then create associated emails, t, calls and trades to the scenario.
There is a 1:many relationship with the scenario and the communications. The issue I am having is I want the user to be able to click the scenario, it then shows the filtered list of communications, each communication source is a tab. The way I am filtering the communication is based on the id of the foreign key on the object. However if there is no entry for the datasource I receive a "no reverse match" because I am using the scenario id from the first object and that doesnt exist if there is no communication for that scenario.
I am stumped on what the best way to do this, besides removing tabs which I like.
Please let me know if I am missing anything, I am relatively new to programming and very new to Django.
models.py
from __future__ import unicode_literals
from django.db import models
from django.core.urlresolvers import reverse
class Scenario(models.Model):
name = models.CharField(max_length=256, blank=False, null=False, unique=True)
description = models.TextField(max_length=1000)
def get_absolute_url(self):
return reverse('scenarios:detail', kwargs={'pk': self.pk})
def __unicode__(self):
return self.name
class Email(models.Model):
scenario = models.ForeignKey(Scenario, on_delete=models.CASCADE )
recipient_email = models.EmailField()
sender_email = models.EmailField()
subject = models.CharField(blank=True, null=False, max_length=256)
body = models.TextField(blank=True, null=False, max_length=2048)
# timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
# updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def get_absolute_url(self):
return reverse('scenarios:email-index')
def __unicode__(self):
return self.sender_email + ' ' + self.recipient_email + ' ' + self.subject
class InstantMessage(models.Model):
NETWORKS = (
('Yahoo', 'Yahoo'),
('MSN', 'MSN'),
('Skype', 'Skype')
)
scenario = models.ForeignKey(Scenario, on_delete=models.CASCADE)
description = models.CharField(max_length=256, null=False, blank=False)
network = models.CharField(max_length=50, null=False, blank=False, choices=NETWORKS)
room = models.CharField(max_length=100, null=False, blank=False)
starttime = models.TimeField(blank=False, null=False)
endtime = models.TimeField(blank=False, null=False)
participant1 = models.CharField(max_length=256, null=False, blank=False)
participant2 = models.CharField(max_length=256, null=False, blank=False)
chatcsv = models.FileField(upload_to='chatfiles')
def get_absolute_url(self):
return reverse('scenarios:im-index')
def __unicode__(self):
return "Network=" + self.network + " Description:" + self.description
class VoiceCall(models.Model):
DIRECTION = (
('outbound', 'Outbound'),
('inbound', 'Inbound')
)
scenario = models.ForeignKey(Scenario, on_delete=models.CASCADE)
description = models.CharField(max_length=256, null=False, blank=False)
direction = models.CharField(choices=DIRECTION, null=False, blank=False, default="Outbound", max_length=15)
starttime = models.TimeField(blank=False, null=False)
endtime = models.TimeField(blank=False, null=False)
traderid = models.CharField(max_length=50,blank=False, null=False)
diallednumber = models.BigIntegerField(blank=True, null=True)
cli = models.BigIntegerField(blank=True, null=True)
nameofcaller = models.CharField(max_length=100, blank=True, null=True)
nameofline = models.CharField(max_length=100, blank=True, null=True)
wavfile = models.FileField(upload_to='voice')
transcript = models.FileField(blank=True, null=True, upload_to='voice')
bagofwords = models.FileField(blank=True, null=True, upload_to='voice')
def get_absolute_url(self):
return reverse('scenarios:call-index')
def __unicode__(self):
return self.description
class Trade(models.Model):
scenario = models.ForeignKey(Scenario, on_delete=models.CASCADE)
tradeprefix = models.CharField(max_length=6, null=False, blank=False)
trader = models.CharField(max_length=256, null=False, blank=False)
sales = models.CharField(max_length=256, null=False, blank=False)
counterpartyid = models.CharField(max_length=256, null=False, blank=False)
counterpartyname = models.CharField(max_length=256, null=False, blank=False)
brokerid = models.CharField(max_length=256, null=False, blank=False)
brokername = models.CharField(max_length=256, null=False, blank=False)
isevent = models.BooleanField(default=False)
def get_absolute_url(self):
return reverse('scenarios:trade-index')
# def __unicode__(self):
# return self.description
class Mobile(models.Model):
scenario = models.ForeignKey(Scenario, on_delete=models.CASCADE)
displayname = models.CharField(max_length=100, null=False, blank=False)
email = models.EmailField()
tonumber = models.BigIntegerField(blank=True, null=True)
fromnumber = models.BigIntegerField(blank=True, null=True)
message = models.CharField(blank=True, null=False, max_length=1024)
def get_absolute_url(self):
return reverse('scenarios:mobile-index')
views.py
class IMScenarioList(generic.ListView):
model = InstantMessage
template_name = 'scenarios/im_filtered.html'
context_object_name = 'scenario_ims'
def get_queryset(self):
return InstantMessage.objects.filter(scenario=self.kwargs['pk'])
class CallScenario(generic.ListView):
model = VoiceCall
template_name = 'scenarios/call_filtered.html'
context_object_name = 'scenario_calls'
def get_queryset(self):
return VoiceCall.objects.filter(scenario=self.kwargs['pk'])
class MobileScenario(generic.ListView):
model = Mobile
template_name = 'scenarios/mobile_filtered.html'
context_object_name = 'scenario_mobiles'
def get_queryset(self):
return Mobile.objects.filter(scenario=self.kwargs['pk'])
class TradeScenario(generic.ListView):
model = Trade
template_name = 'scenarios/trades_filtered.html'
context_object_name = 'trades'
def get_queryset(self):
return Trade.objects.filter(scenario=self.kwargs['pk'])
urls.py
url(r'^(?P<pk>[0-9]+)/email/$', views.EmailScenarioList.as_view(), name='email-scenario'),
# Instant Messages
url(r'^im/$', views.IMList.as_view(), name='im-index'),
url(r'^im/add/$', views.IMCreate.as_view(), name='im-create'),
url(r'^im/(?P<pk>[0-9]+)/update/$', views.IMUpdate.as_view(), name='im-update'),
url(r'^im/(?P<pk>[0-9]+)/delete/$', views.IMDelete.as_view(), name='im-delete'),
url(r'^(?P<pk>[0-9]+)/im/$', views.IMScenarioList.as_view(), name='im-scenario'),
# Voice Calls
url(r'^calls/$', views.CallList.as_view(), name='call-index'),
url(r'calls/add/$', views.CallCreate.as_view(), name='call-create'),
url(r'^calls/(?P<pk>[0-9]+)/update/$', views.CallUpdate.as_view(), name='call-update'),
url(r'^calls/(?P<pk>[0-9]+)/delete/$', views.CallDelete.as_view(), name='call-delete'),
url(r'^(?P<pk>[0-9]+)/voice/$', views.CallScenario.as_view(), name='call-scenario'),
# trades
url(r'^trades/$', views.TradeList.as_view(), name='trade-index'),
url(r'^trades/add/$', views.TradeCreate.as_view(), name='trade-create'),
url(r'^trades/(?P<pk>[0-9]+)/update/$', views.TradeUpdate.as_view(), name='trade-update'),
url(r'^trades/(?P<pk>[0-9]+)/delete/$', views.TradeDelete.as_view(), name='trade-delete'),
url(r'^(?P<pk>[0-9]+)/trade/$', views.TradeScenario.as_view(), name='trade-scenario'),
# mobile
url(r'^mobile/$', views.MobileList.as_view(), name='mobile-index'),
url(r'^mobile/add/$', views.MobileCreate.as_view(), name='mobile-create'),
url(r'^mobile/(?P<pk>[0-9]+)/update/$', views.MobileUpdate.as_view(), name='mobile-update'),
url(r'^mobile/(?P<pk>[0-9]+)/delete/$', views.MobileDelete.as_view(), name='mobile-delete'),
url(r'^(?P<pk>[0-9]+)/mobile/$', views.MobileScenario.as_view(), name='mobile-scenario'),
Templates
trade_index.html
{% extends 'base.html' %}
{% block content %}
<div class="container">
<table id="myTable" class="tablesorter tablesorter-bootstrap">
<thead>
<tr>
<th class="first-name filter-select" data-placeholder="Select a Scenario">Scenario</th>
<th></th>
<th>Trade Prefix</th>
<th>Trader</th>
<th>Sales</th>
<th>Counterparty ID</th>
<th class="first-name filter-select" data-placeholder="Select Counterparty">Counterparty Name</th>
<th>Broker ID</th>
<th></th>
<th class="first-name filter-select" data-placeholder="Select Broker">Broker Name</th>
<th class="first-name filter-select" data-placeholder="IsEvent">IsEvent</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{% for trade in trades %}
<tr>
<td data-toggle="tooltip" title="Description: {{trade.scenario.description}}">{{trade.scenario}}</td>
<td></td>
<td>{{trade.tradeprefix}}</td>
<td>{{trade.trader}}</td>
<td>{{trade.sales}}</td>
<td>{{trade.counterpartyid}}</td>
<td>{{trade.counterpartyname}}</td>
<td>{{trade.brokerid}}</td>
<td></td>
<td>{{trade.brokername}}</td>
<td>{{trade.isevent}}</td>
<td>
<a href="{% url 'scenarios:trade-update' trade.id %}">
<button type="submit" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-pencil" />
</button>
</a>
</td>
<td><form action="{% url 'scenarios:trade-delete' pk=trade.id %}" method="post">
{% csrf_token %}
<input type="hidden" name="call_id" value="{{ trade.id}}"/>
<button type="submit" class="btn btn-default btn-sm" onclick="return confirm('Are you sure you want to delete {{trade.description}}?')">
<span class="glyphicon glyphicon-trash" />
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{% url 'scenarios:trade-create' %}">
<button type="submit" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-plus" />
</button>
</a> Add Trade
<br>
<button type="button" class="btn btn-default btn-sm" value="Back" onClick="javascript:history.go(-1);">
<span class="glyphicon glyphicon-backward" />
</button>
</div>
{% endblock %}
trades_filtered.html
{% extends 'scenarios/trade_index.html' %}
{% block content %}
{% with trades|first as first_trade %}
<ul class="nav nav-pills">
<li class="active">trades</li>
<li>emails</li>
<li>instant messages</li>
<li>voice</li>
<li>mobile</li>
</ul>
{% endwith %}
{{ block.super }}
{% endblock %}
Right now in trades_filtered.html you take the ID of a given scenario and use that ID to manually construct your five URLs. If it were me, I'd use a custom model method to determine whether or not we need to generate a URL first.
class Scenario(models.Model):
name = models.CharField(max_length=256, blank=False, null=False, unique=True)
description = models.TextField(max_length=1000)
def generate_trade_url(self):
if self.trade_set.exists():
return reverse('scenarios:trade-scenario', kwargs={'pk':self.pk})
return None
def generate_email_url(self):
...
You would need one method like this for each URL you want to generate. You can this use this logic either in the view (preferable) or in your template (simpler but slower) to dynamically generate your URLs only when they are valid.
EDIT: I just looked at this answer a second time. I included null=False in the name field definition because it was in the original, but be aware that it doesn't actually do anything useful on a CharField. Django doesn't use null values for those fields, instead storing them as '' (empty string).
Related
i want to sort product list by pricing low to high and high to low and render in template
my models.py
class Item(models.Model):
categories = models.ForeignKey(Categories, on_delete=models.CASCADE, related_name='our_items')
subcategories = models.ForeignKey(Subcategories, on_delete=models.CASCADE, related_name='products')
can_buy = models.ForeignKey(For, on_delete=models.CASCADE, related_name='for_wearing')
name = models.CharField(max_length=200, blank=False)
contain_size = models.CharField(max_length=50, blank=True)
brand_name = models.CharField(max_length=100, blank=False, default='Bagh')
first = models.ImageField(upload_to='items', blank=False)
second = models.ImageField(upload_to='items', blank=False)
third = models.ImageField(upload_to='items', blank=True)
fourth = models.ImageField(upload_to='items', blank=True)
fifth = models.ImageField(upload_to='items', blank=True)
rating = models.FloatField(blank=False,default='4.0')
item_video = models.FileField(upload_to='item_vedio', blank=True)
color = models.CharField(max_length=30, blank=False, default='Black')
material = models.CharField(max_length=50, blank=False, default='Plastic' )
return_policy = models.CharField(max_length=100, blank=False, default='7Days Return Policy')
stock = models.CharField(max_length=50, blank=False, default='In Stock')
price = models.FloatField(blank=False,)
actual_price = models.FloatField(blank=False)
type = models.CharField(blank=False, max_length=100, default='washable')
about = models.CharField(blank=False,max_length=100, default='Lusturous')
offer = models.CharField(max_length=4, blank=True)
joined_date = models.DateTimeField(default=timezone.now,editable=False)
update_at = models.DateTimeField(auto_now=True)
description = models.TextField(blank=True)
def __str__(self):
return self.name
class Subcategories(models.Model):
categories = models.ForeignKey(Categories, on_delete=models.CASCADE, related_name='our_categories')
name = models.CharField(max_length=200, blank=False)
joined_date = models.DateTimeField(default=timezone.now,editable=False)
update_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
here is my views.py
class Product(View):
def get(self, request, subcategory_id):
subcategory = get_object_or_404(Subcategories, pk=subcategory_id)
products = subcategory.products.all()
category_list = Categories.objects.all()
print(products)
return render (request, 'products.html',{"subcategory_list" : products, 'category_list': category_list })
my html
<div class="col-10">
<ul>
<li class="filters"><strong>Sort By :</strong></li>
<li class="filters"><a class="filter_by" href="">Popularity</a></li>
<li class="filters"><a class="filter_by" href="">Price:--low to high</a></li>
<li class="filters"><a class="filter_by" href="">Price:-- high to low</a></li>
<li class="filters"><a class="filter_by" href="">Newest First</a></li>
<li class="filters"><a class="filter_by" href="">Discount</a></li>
</ul>
</div>
<section class="col-10">
{% for products in subcategory_list %}
<a class="products" href="{% url 'products:detail' item_id=products.id %}">
<div class="card col-4" style="width: 18rem; height:420px">
<img class="img" src="{{ products.first.url }}" alt="" height="300px" width="100%" onmouseover="this.src='{{ products.second.url }}'"
onmouseout="this.src='{{ products.first.url }}'" >
<div class="detail">
<h4 class="price">{{ products.price|currency}}</h4>
<h5>{{products.name}} <br> <span class="brand">{{ products.brand_name}}</span> <span class="btn btn-success buton">✔Authentic</span> </h5>
<p class="rate">Rate: {{products.rating}}<i class="fas fa-star"></i></p>
<h6>Size:<span> {{products.contain_size}}</span> </h6>
</div>
</div>
</a>
{% endfor %}
</div>
</section>
as you can see i created a div and in that i put sorting so what i want when a user click on that link it render the product list in that order but right i have no idea how to that i saw some document but that doesn't seem the best way to achieve that any idea which is the best way to achieve that
thank you for your time
In your html
<li class="filters"><a class="filter_by" href="?sort=l2h">Price:--low to high</a></li>
<li class="filters"><a class="filter_by" href="?sort=h2l">Price:-- high to low</a></li>
In your view
def get(self, request, subcategory_id):
subcategory = get_object_or_404(Subcategories, pk=subcategory_id)
sort_by = request.GET.get("sort", "l2h")
if sort_by == "l2h":
products = subcategory.products.order_by("price")
elif sort_by == "h2l":
products = subcategory.products.order_by("-price")
category_list = Categories.objects.all()
return render (request, 'products.html',{"subcategory_list" : products, 'category_list': category_list })
Explanation :
When you click on the sorting link from frontend, just look out at your url in browser.
We are sending a sort parameter which tells how should we sort it.
We retrieve that parameter in our view
sort_by = request.GET.get("sort", "l2h")
Note : Here if no parameter is provided ( When user visits that page ) it will be sorted by l2h aka low to high
You can change that accordingly, what default sorting/filtering you want
Finally, we are just using django query to filter out our data.
And use that in your template
how to save data from html table in django without using form.py. I am currently creating table in html with add button and after adding all rows in table i want to save it but i am not using form.py only view.py,html,model.py
my view code is below
views.py
school_name = request.POST['school_name']
m_pass_out = request.POST['m_pass_out']
medicalschool = MedicalSchool(school_name=school_name, m_pass_out=m_pass_out)
medicalschool.save()
my model code is below
models.py
class DoctorProfile(models.Model):
user_guid = models.OneToOneField(
'EgdEradUsers', models.DO_NOTHING, db_column='user_guid', primary_key=True)
doctor_guid = models.UUIDField(unique=True)
featured_doctor_id = models.BooleanField()
primary_speciality = models.ForeignKey(DSpecialtyType, models.DO_NOTHING)
# This field type is a guess.
secondary_speciality = models.TextField(blank=True, null=True)
years_experience = models.IntegerField()
# This field type is a guess.
education = models.TextField(blank=True, null=True)
license_number = models.CharField(max_length=1000, blank=True, null=True)
npi_number = models.CharField(max_length=1000, blank=True, null=True)
revalidation_cme = models.IntegerField(blank=True, null=True)
# This field type is a guess.
states_to_practice = models.TextField(blank=True, null=True)
# This field type is a guess.
board_certification = models.TextField(blank=True, null=True)
# This field type is a guess.
honors_awards_recognition = models.TextField(blank=True, null=True)
# This field type is a guess.
publications = models.TextField(blank=True, null=True)
description = models.CharField(max_length=1000, blank=True, null=True)
# This field type is a guess.
hospital_privileges = models.TextField(blank=True, null=True)
phone_code = models.IntegerField(blank=True, null=True)
primary_contact_number = models.CharField(max_length=45)
phone_code2 = models.IntegerField(blank=True, null=True)
secondary_contact_number = models.CharField(
max_length=45, blank=True, null=True)
resume_url = models.CharField(max_length=1000, blank=True, null=True)
avatar_url = models.CharField(max_length=1000, blank=True, null=True)
additional_comments = models.CharField(
max_length=1000, blank=True, null=True)
class Meta:
managed = True
db_table = 'doctor_profile'
class MedicalSchool(models.Model):
school_name = models.CharField(max_length=100)
m_pass_out = models.DateField(max_length=100)
doctor_profile = models.ForeignKey(DoctorProfile, on_delete=models.CASCADE)
created_at = models.DateTimeField()
updated_at = models.DateTimeField(blank=True, null=True)
class Meta:
db_table = 'medical_school'
my html code is below
html
<div class="container-lg">
<div class="table-responsive">
<div class="table-wrapper">
<div class="table-title">
<div class="row">
<div class="col-sm-8">
<h2>Medical School</h2>
</div>
<div class="col-sm-4">
<button type="button" id="medical" class="btn btn-info add-
new"><i class="fa fa-plus"></i> Add New</button>
</div>
</div>
</div>
<table id="medicaltable" class="table table-bordered">
<thead>
<tr>
<th>Name of School</th>
<th>Year of Graduation</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td id="medicaltext" name="school_name"></td>
<td id="medicaldate" name="m_pass_out"></td>
<td>
<a id="medicaladd" class="add" title="Add" data-
toggle="tooltip"><i class="material-icons"></i></a>
<a id="medicaledit" class="edit" title="Edit" data-
toggle="tooltip"><i class="material-icons"></i></a>
<a id="medicaldelete" class="delete" title="Delete" data-
toggle="tooltip"><i class="material-icons"></i></a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
you can access to your each html form inputs by their name in view. see below code:
models
from django.db import models
from django import forms
class MedicalSchool(models.Model):
school_name = models.CharField(max_length=100)
m_pass_out = models.DateField(max_length=100)
doctor_profile = models.ForeignKey(DoctorProfile, on_delete=models.CASCADE)
created_at = models.DateTimeField()
updated_at = models.DateTimeField(blank=True, null=True)
class Meta:
db_table = 'medical_school'
class MedicalSchoolForm(forms.ModelForm):
class Meta:
model = MedicalSchool
fields = ['school_name', 'm_pass_out', 'doctor_profile']
views
from django.contrib import messages
from django.shortcuts import redirect, render
from . import models
def MedicalSchool(request):
url = request.META.get('HTTP_REFERER') # get last url
if request.method == 'POST':
form = models.MedicalSchoolForm(request.POST) # access to ModelForm
if form.is_valid():
data = models.MedicalSchool() # create a instance of your Model
data.school_name = form.cleaned_data['school_name'] # 'school_name' is the name that we specified in html form input
data.m_pass_out = form.cleaned_data['m_pass_out'] # 'm_pass_out' is the name that we specified in html form input
data.doctor_profile_id = form.cleaned_data['doctor_profile'] # 'doctor_profile' is the name that we specified in html form input
data.save()
return redirect(url)
else:
messages.warning(request, form.errors)
return redirect(url)
context = {'DoctorProfile': models.DoctorProfile.objects.all()}
return render(request, 'MedicalSchool.html', context)
urls
from django.urls import path
from . import views
app_name = 'School'
urlpatterns = [
path('', views.MedicalSchool, name='MedicalSchool'),
...
]
MedicalSchool.html
<form action="{% url 'School:MedicalSchool' %}" method="POST">
{% csrf_token %}
<input type="text" name="school_name" placeholder="school name" required>
<input type="text" name="m_pass_out" placeholder="m pass out" required>
<select name='doctor_profile'>
{% for dr in DoctorProfile %}
<option name="doctor_profile" value="{{ dr.id }}">{{ dr.title}}</option> <!-- Match your code with {{ dr.title}} -->
{% endfor %}
</select>
<button type="submit"> Submit </button>
</form>
let me know if there was a problem
I have a contact and an event model where the event model has a foreign key to contact. The first half of my html obviously works, but for some reason when I display the list of other events that the contact has done, I can't get the list to show up. Is it because I'm calling {{event.whatever}} twice on the same page but in two differrent context?
views.py
class EventDetail(DetailView):
template_name = 'crm/eventdetail.html'
model = Event
models.py
class Contact(models.Model):
firstname = models.CharField(max_length=20, null=True, blank=True)
lastname = models.CharField(max_length=20, null=True, blank=True)
email = models.CharField(max_length=40, null=True, blank=True)
phone = models.CharField(max_length=15, null=True, blank=True)
title = models.CharField(max_length=20, null=True, blank=True)
notes = models.CharField(max_length=400, null=True, blank=True)
company = models.ForeignKey(Company, on_delete=models.CASCADE, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ["lastname"]
def __str__(self):
return self.firstname
class Event(models.Model):
event_type = models.CharField(max_length=20, choices = event_types)
contact = models.ForeignKey(Contact, on_delete=models.CASCADE)
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
should_follow_up = models.BooleanField(default=False)
date = models.DateField()
notes = models.CharField(max_length=400)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def get_absolute_url(self):
return reverse('events_detail', kwargs={'pk': self.pk})
eventdetail.html
<div id="container">
<h1> Event: {{event.event_type}} </h1>
<ul>
<li>Event Contact: {{event.contact}}</li>
<li>Created By: {{event.created_by}}</li>
<li>Date: {{event.date}}</li>
<li>Note: {{event.notes}}</li>
</ul>
<h1>Events for {{event.contact}}</h1>
<table class="table">
<tr>
<th scope="col">Event Type</th>
<th scope="col">Date</th>
<th scope="col">3</th>
</tr>
{% for event in contact.event_set.all %}
<tr>
<td> {{event.event_type}}</td>
<td> {{event.date}}</td>
<td> </td>
</tr>
{% endfor %}
</table>
<p>This event was inputted on {{event.created}} and last edited on {{event.updated}}</p>
</div>
The for loop which is supposed to display all the other events the contact has done is not showing up. Any help is appreciated
Changes my view
class EventDetail(DetailView):
def get(self, request, *args, **kwargs):
event = get_object_or_404(Event, pk=kwargs['pk'])
events = event.contact.eventss.all()
context = {'event': event, 'events':events}
return render(request, 'crm/eventdetail.html', context)
Added a related_name to my model
contact = models.ForeignKey(Contact, related_name='eventss', on_delete=models.CASCADE)
Here is the html file that finally worked
{% for events in event.contact.eventss.all %}
<tr>
<td>{{events.event_type}}</td>
<td>{{events.date}}</td>
<td> </td>
</tr>
{% endfor %}
I am having a one to one relationship between 2 models. While creating the second model, I want to pass the instance of the first model to the second one.
These 2 models are new tabs/features in our web application. I tried passing the instance through URL but didn't succeed. Maybe I am not following steps correctly.
Details about:
python version: Python 3.6.4 :: Anaconda, Inc.
django version: 2.0.2-3
Please find below the code:
1) models.py
class StudyConcept(models.Model):
requestor_name = models.CharField(max_length=240, blank=False, null=False)
project = models.CharField(max_length=240, blank=False, null=False)
date_of_request = models.DateField(blank=False, null=False)
brief_summary = models.CharField(max_length=4000, blank=False, null=False)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return str(self.id)
class Logistics(models.Model):
budget = models.CharField(max_length=255, blank=False, null=False)
business_technology = models.CharField(max_length=3, choices=CHOICES, blank=False, null=False)
vendor_or_contracts = models.CharField(max_length=3, choices=CHOICES, blank=False, null=False)
studyConcept = models.OneToOneField(StudyConcept, on_delete = models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return str(self.id)
def get_absolute_url(self):
return reverse('update_Logistics', kwargs={'pk': self.pk})
def get_deliverablesLogistics(self):
return ','.join([str(i) for i in self.deliverablesLogistics.all().values_list('id', flat=True)])
def get_paymentScheduleLogistics(self):
return ','.join([str(i) for i in self.paymentScheduleLogistics.all().values_list('id', flat=True)])
def get_commentsLogistics(self):
return ','.join([str(i) for i in self.commentsLogistics.all().values_list('id', flat=True)])
class DeliverablesLogistics(models.Model):
milestone_deliverable = models.CharField('MileStone/Deliverable', max_length=480, blank=False, null=False)
poa = models.CharField('POA', max_length=480, blank=False, null=False)
start_date = models.DateField(blank=False, null=False)
end_date = models.DateField(blank=False, null=False)
logistics = models.ForeignKey(Logistics, related_name='deliverablesLogistics', on_delete=models.CASCADE)
def __str__(self):
return str(self.id)
class PaymentScheduleLogistics(models.Model):
milestone_deliverable = models.CharField('MileStone/Deliverable', max_length=480, blank=False, null=False)
cost = models.DecimalField(max_digits=14, decimal_places=2, blank=False, null=False, default=0)
estimated_payment_date = models.DateField(blank=False, null=False)
logistics = models.ForeignKey(Logistics, related_name='paymentScheduleLogistics', on_delete=models.CASCADE)
def __str__(self):
return str(self.id)
class CommentsLogistics(models.Model):
comments = models.CharField('Comment', max_length=2000, blank=True, null=True)
commented_by = models.CharField(max_length=2000, blank=True, null=True)
logistics = models.ForeignKey(Logistics, related_name='commentsLogistics', on_delete=models.CASCADE)
def __str__(self):
return str(self.id)
views.py
def load_concepts(request):
currentUser = User.objects.get(id=request.user.id)
concepts = StudyConcept.objects.all().filter(user=request.user)
#concepts = get_object_or_404(StudyConcept)
return render(request, 'concept_dropdown_list_options.html',{
'concepts':concepts
})
class LogisticsFormsetCreate(CreateView):
model = Logistics
template_name = 'createLogistics.html'
form_class = LogisticsForm
success_url = reverse_lazy('create_Logistics')
def get_context_data(self, **kwargs):
data = super(LogisticsFormsetCreate, self).get_context_data(**kwargs)
if self.request.POST:
data['deliverable'] = DeliverablesLogisticsFormset(self.request.POST, prefix='deliverables')
data['paymentSchedule'] = PaymentScheduleLogisticsFormset(self.request.POST, prefix='payments')
data['comment'] = CommentsLogisticsFormset(self.request.POST, prefix='comments')
#data['studyRequestConcept'] = self.request.POST.get('studyRequestConcept')
else:
data['deliverable'] = DeliverablesLogisticsFormset(prefix='deliverables')
data['paymentSchedule'] = PaymentScheduleLogisticsFormset(prefix='payments')
data['comment'] = CommentsLogisticsFormset(prefix='comments')
#data['studyRequestConcept'] = self.request.GET.get('studyRequestConcept')
return data
def form_valid(self, form):
context = self.get_context_data()
deliverable = context['deliverable']
paymentSchedule = context['paymentSchedule']
comment = context['comment']
with transaction.atomic():
if deliverable.is_valid() and paymentSchedule.is_valid() and comment.is_valid():
self.object = form.save(commit=False)
self.object.user = self.request.user
self.object = form.save()
deliverable.instance = self.object
deliverable.save()
paymentSchedule.instance = self.object
paymentSchedule.save()
comment.instance = self.object
comment.save()
messages.success(self.request, Logistics.__name__ +' Form ID: '+ str(self.object.id) + ' was submitted successfully')
return super(LogisticsFormsetCreate, self).form_valid(form)
else:
return self.render_to_response(self.get_context_data(form=form))
Template
{% extends "header.html" %}
{% load widget_tweaks %}
{% block content %}
{% csrf_token %}
{% include 'xdsoft_stylesheets.html' %}
{% include 'messages.html' %}
<div class="container" align="center">
<h1 class="display-5">Logistics</h1>
</div>
<br/>
<div class="table-responsive">
<table class="table table-striped table-bordered" id="example" data-toggle="table"
data-filter-control="true" data-show-export="true"
data-click-to-select="true" data-toolbar="#toolbar" data-escape>
<thead>
<tr>
<th></th>
<th class="text-center" data-field="id" data-filter-control="input">ID</th>
<th class="text-center" data-field="project" data-filter-control="input">Project</th>
<th class="text-center" data-field="date_of_request" data-filter-control="input">Date</th>
<th class="text-center" data-field="brief_summary" data-filter-control="input">Summary</th>
<th class="text-center" data-field="scientific_question" data-filter-control="input">Question</th>
</tr>
</thead>
<tbody>
{%for studyRequestConcept in concepts %}
<tr>
<td style="width:200px">
<a class=" btn btn-primary js-create-logistics" data-toggle="modal" data-target="#modal" href="{% url 'create_Logistics' %}">
<span class="glyphicon glyphicon-plus"></span>
New Logistics
</a>
</td>
<td class="text-left">{{studyRequestConcept.id}}</td>
<td class="text-left">{{studyRequestConcept.project}}</td>
<td class="text-left">{{studyRequestConcept.date_of_request}}</td>
<td class="text-left">{{studyRequestConcept.brief_summary}}</td>
<td class="text-left">{{studyRequestConcept.scientific_question}}</td>
</tr>
{% endfor%}
</tbody>
</table>
</div>
{% comment %}The modal container{% endcomment %}
<div class="modal" id="modal" data-backdrop="false"></div>
<script>
$(function () {
$('.js-create-logistics').click( function () {
var btn = $(this)
$.ajax({
url: btn.attr("href"),
context: document.body
}).done(function(response) {
$("#modal").html(response);
});
});
});
</script>
{% endblock %}
I have a view/template where I list all the Study Concepts and every row has a create new Logistics button next to it. After clicking create new logistics button, the modal/view will open that will allow you to create a new Logistics. I want to pass the instance of the object study concept when I click the button.
Also, CreateLogistics is a class-based view designed using "from django.views.generic import CreateView"
I will be more than happy to provide any further code or information needed. Thanks in advance for all the support and help.
Regards,
Amey Kelekar
You haven't shown your URLs, but you need to accept the ID in the URL for the CreateView and use it in form_valid. For example:
path('/create_logistics/<int:id>/', LogisticsFormsetCreate.as_view(), name="create_Logistics"),
So in the template you would do:
<a class="btn btn-primary js-create-logistics" data-toggle="modal" data-target="#modal" href="{% url 'create_Logistics' id=studyRequestConcept.id %}">
and in the view:
def form_valid(self, form):
...
self.object = form.save(commit=False)
self.object.user = self.request.user
self.object.studyConcept_id = self.kwargs['id']
self.object.save()
...
I have a case, where on my template view I would like to display list of all objects (Issues) and categories (Sprints). I already applied also another filtering to display Issues that belongs to particular Project.
I've managed so far to display Sprints and within each Sprint I am displaying list of issues. How can I apply additional filtering on issues, that only issues belongs to particular sprint will be displayed?
Final result should be to display list of all issues divided per sprint.
My code below:
#views.py
class ProjectBacklogView(DetailView):
model = Project
template_name = 'project-backlog.html'
context_object_name = 'backlog'
def get_context_data(self, **kwargs):
context = super(ProjectBacklogView, self).get_context_data(**kwargs)
context['project'] = Project.objects.all()
context['issue'] = Issue.objects.all().order_by('sprint')
# context['epic'] = Epic.objects.all()
# context['initiative'] = Initiative.objects.all()
context['sprint'] = Sprint.objects.all()
return context
# template.html
{% extends 'base-project.html' %}
{% block content %}
{% for sprint in backlog.sprint_set.all %}
<h4>{{ sprint.name }}</h4>
<div id="simpleList" class="list-group" style="margin-bottom: 2%;">
{% for issue in backlog.issue_set.all %}
<div class="list-group-item">
<div style="float:left;"><strong>{{ issue.title }}</strong></div>
<div style="float: right;"><i class="fas">{{ issue.remaining_estimate }}</i></div>
<br /><br /><hr style="border-top: dashed 1px;"></hr>
<div style="float: left;"><small>Assignee: <strong>{{ issue.assignee }}</strong></small></div>
<div style="float: right;"><small>Initiative: <strong>{{ issue.initiative }}</strong></small></div><br />
<div style="float: left;"><small>Priority: <strong>{{ issue.priority }}</strong></small></div>
<div style="float: right;"><small>Epic: <strong>{{ issue.epic }}</strong></small></div>
</div>
{% endfor %}
<br />
</div>
{% endfor %}
{% endblock %}
#models.py
class Project(models.Model):
PROJECT_TYPE = (
('SCR', 'Scrum'),
('KAN', 'Kanban'),
)
# slug = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
alias = models.CharField(max_length=8, primary_key=True)
name = models.CharField(max_length=160)
project_type = models.CharField(max_length=10, choices=PROJECT_TYPE, default="SCR")
lead = models.ForeignKey(CustomUser, on_delete=models.CASCADE, null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True)
# Definicja nazwy modelu w Adminie Django
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('project-detail', args=[str(self.alias)])
class Sprint(models.Model):
# sprint_type = models.TextField(default='Sprint', editable=False)
name = models.CharField(max_length=32)
goal = models.TextField(null=True, blank=True)
start_date = models.DateField()
end_date = models.DateField()
project = models.ForeignKey(Project, on_delete=models.CASCADE)
def __str__(self):
return self.name
class Issue(models.Model):
ISSUE_PRIORITY = (
('Critical', 'C'),
('High', 'H'),
('Medium', 'M'),
('Low', 'L'),
)
issue_type = models.TextField(default='Issue', editable=False)
issue_id = models.AutoField(primary_key=True)
# slug = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
date_created = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
title = models.CharField(max_length=128)
description = models.TextField(null=True, blank=True)
initiative = models.ForeignKey(Initiative, on_delete=models.CASCADE, null=True, blank=True)
epic = models.ForeignKey(Epic, null=True, blank=True, on_delete=models.CASCADE)
sprint = models.ForeignKey(Sprint, on_delete=models.CASCADE, null=True, blank=True)
priority = models.CharField(max_length=8, choices=ISSUE_PRIORITY, default='Medium')
assignee = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='assignees', null=True, blank=True) # zczytywane z tabeli userów
author = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='authors') # zczytywane z tabeli userów
remaining_estimate = models.IntegerField(null=True, blank=True, default='0') # w minutach
time_logged = models.IntegerField(default='0') # w minutach
attachment = models.FileField(null=True, blank=True) # To Do - multiple files??
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('issue-detail', args=[str(self.issue_id)])
My issue is I don't know how to apply dynamically filter (based on field sprint) as sprints are listed in for loop