I am using Inlineformsets for an app. Data gets saved but when I retrieve data, main form data is correctly retrieved however in case of childmodel, only first raw is retrieved from DB.
Views.py
#login_required
def invoice_detail(request,pk):
invoice_detailmain = serviceinvoice.objects.get(pk=pk)
if invoice_detailmain.user != request.user:
raise PermissionDenied
invoiceitems =invoice_detailmain.serviceitems1.filter(pk=pk,user=request.user)
return render(request,'account/invoicedetail.html',{'invoice_detailmain':invoice_detailmain,
'invoiceitems':invoiceitems})
template.html
{% for items in invoiceitems %}
<tr><td>{{ items.Product }}</td>
<td>{{ items.UOM }}</td>
<td>{{ items.Quantity }}</td>
<td>{{ items.Rate }}</td>
<td>{{ items.Tax_rate }}</td></tr>
{% endfor %}
models.py
class serviceinvoice(models.Model):
user=models.ForeignKey(settings.AUTH_USER_MODEL,related_name='invoice')
invoice_number=models.PositiveIntegerField()
#invoice_no = models.CharField(max_length = 500, default = increment_invoice_number, null = True, blank = True)
invoice_date = models.DateField()
invoice_receivable=models.ForeignKey(Receivables,null=True)
total_amount=models.DecimalField(decimal_places=2,max_digits=20)
total_amountwithtax=models.DecimalField(decimal_places=2,max_digits=20)
company_det=models.ForeignKey(Company,related_name='companydetails')
class Meta:
unique_together = (("user", "invoice_number"),)
ordering=('-invoice_number',)
def __str__(self):
return self.invoice_number
def get_absolute_url(self):
return reverse('invoice:editinvoice', args=[self.invoice_number])
class serviceinvoiceitems(models.Model):
user=models.ForeignKey(settings.AUTH_USER_MODEL,related_name='serviceinvoiceitems')
invoice_number=models.ForeignKey(serviceinvoice,related_name='serviceitems1')
Product=models.CharField(max_length=1000,null=True)
UOM=models.CharField(max_length=100,null=True)
Quantity=models.FloatField(null=True)
Rate=models.FloatField(null=True)
Tax_rate=models.FloatField(null=True)
def __str__(self):
return self.invoice_number
I believe that your filtering is incorrect. Instead of
invoiceitems = invoice_detailmain.serviceitems1.filter(pk=pk,user=request.user)
you should be using
invoiceitems = invoice_detailmain.serviceitems1.filter(user=request.user)
Although I'm baffled to why you have a primary key from both serviceinvoice and serviceinvoiceitems to your user model. It would probably be enough for you to specify
invoiceitems = invoice_detailmain.serviceitems1.all()
Related
I am trying to query the database to display results from the form. Once I select the form drop-down fields for my wanted query e.g. Ford C-Max 2019 1.2 Petrol 1500 , from which I coded for now to display results (regardless of Make & Model as I only have one atm) , then instead of showing me the table with matched results I get this error:
Request Method: POST
Request URL: http://127.0.0.1:8000/data/
Django Version: 3.0.3
Exception Type: ValueError
Exception Value:
The view app.views.data didn't return an HttpResponse object. It returned None instead.
However I do have that result in the database table named ford_cmax (ignore the average & entered columns)
average entered year liter fuel mileage
9701 2020-04-08 20:59:45 2019 1.2 Petrol 1500
I did not have this problem before, the table showed all results fine before I did the tweaking for filters.
My code:
views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import FormView
from django.db.models import Q
from .models import Average, Query
from .forms import QueryForm
class QueryMakeModel(FormView):
template_name = 'QueryMakeModel.html'
success_url = '/data/'
form_class = QueryForm
def form_valid(self, form):
return HttpResponse("Sweet.")
def index(request):
if request.method == 'POST':
FormSite = QueryForm(request.POST)
if FormSite.is_valid():
pass
else:
FormSite = QueryForm()
return render(request, 'app/QueryMakeModel.html', {'FormSite': FormSite})
def data(request):
if request.method == 'GET':
query= request.GET.get('q')
if query is not None:
lookups= Q(mileage__icontains= query) & Q(fuel__icontains=query) & Q(liter__icontains=query) & Q(year__icontains=query)
results= Average.objects.filter(lookups).distinct()
context = { 'results': results}
return render(request, 'app/db.html', context)
db.html (Data display page)
table>
<tr>
<th>Year</th>
<th>Liter</th>
<th>Fuel</th>
<th>Mileage</th>
<th>Average</th>
<th>Entered</th>
</tr>
{% for Average in query_results %}
<tr>
<td>{{ Average.year }}</td>
<td>{{ Average.liter }}</td>
<td>{{ Average.fuel }}</td>
<td>{{ Average.mileage }}</td>
<td>{{ Average.average }}</td>
<td>{{ Average.entered }}</td>
</tr>
{% endfor %}
</table>
QueryMakeModel.html (Main Query Form Page)
{% block content %}
<p>Please fill the details below:</p>
<form action="/data/" method="post">{% csrf_token %}
{{ FormSite.as_p }}
<button type="submit">
<i class="fa fa-thumb-tack"></i> Query
</button>
</form>
{% endblock %}
models.py
class Query(models.Model):
MAKE = models.CharField(max_length = 50, choices=MAKES)
MODEL = models.CharField(max_length = 50, choices=MODELS)
YEAR = models.IntegerField(max_length = 4, choices=YEARS)
LITER = models.CharField(max_length = 3, choices=LITERS)
FUEL = models.CharField(max_length = 6, choices=FUELS)
MILEAGE = models.IntegerField(max_length = 10, choices=MILEAGES)
class Average(models.Model):
class Meta:
db_table = 'ford_cmax'
average = models.IntegerField(max_length = 6)
entered = models.DateTimeField(primary_key=True)
year = models.IntegerField(max_length = 4)
liter = models.CharField(max_length = 3)
fuel = models.CharField(max_length = 6)
mileage = models.IntegerField(max_length = 10)
urls.py
from django.contrib import admin
from django.urls import path
from app import views
from django.conf.urls import include, url
from app.views import QueryMakeModel
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index, name='Index'),
path('data/', views.data, name='Data')
]
am understand this by non object in your form from viwes.py but just idea take this way because am not understand your project !!
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.Query = self.request.Query
self.object.save()
return super().form_valid(form)
See the last lines of this code:
def data(request):
if request.method == 'GET':
query= request.GET.get('q')
if query is not None:
lookups= Q(mileage__icontains= query) & Q(fuel__icontains=query) & Q(liter__icontains=query) & Q(year__icontains=query)
results= Average.objects.filter(lookups).distinct()
context = { 'results': results}
return render(request, 'app/db.html', context)
else: #you also have to return an HTTP response in this case
return render(request, 'app/db.html', context)
I have a django model for which I am writing my delete view. I get an django.urls.exceptions.NoReverseMatch error. That is also logical since when I am trying to debug and I want to output my id with {{ model.id }} my view shows me no id at all. When I use the pk it passes in my urls.
My model:
class UrlTrack(models.Model):
url = models.CharField(max_length=255, primary_key=True)
counter = models.BigIntegerField(default=0)
My view:
class AnalyticsDeleteUrls(SingleObjectMixin, View):
model = UrlTrack
def get(self, request, *args, **kwargs):
obj = self.get_object()
if obj is not None:
obj.delete()
return redirect('list_history')
My urls:
path('history/delete/urls/<int:id>/', AnalyticsDeleteUrls.as_view(), name="history_url"),
My template:
{% for item in url_tracks %}
<tr>
<td>{{ item.url }}</td>
<td>{{ item.counter }}</td>
<td> <a class="btn btn-danger" href="{% url 'history_url' item.id %}"> Delete </a>
</tr>
{% endfor %}
Here also my list view:
class AnalyticsIndexView(StaffRequiredMixin, ListView):
template_name = 'analytics_list.html'
model = UrlTrack
context_object_name = 'url_tracks'
queryset = UrlTrack.objects.all()
def get_context_data(self, **kwargs):
context = super(AnalyticsIndexView, self).get_context_data(**kwargs)
context['object_viewed_list'] = ObjectViewed.objects.all()
return context
Why would the id be non existent? I though django passes that in automatically....?
Any help is highly appreciated. Thanks in advance
I think you'll actually need to do it in two steps.
First, add id to the model, then edit the makemigrations file created. You could try modifying your migrations file to something like this:
from __future__ import unicode_literals
from django.db import migrations, models
def set_id(apps, schema_editor):
UrlTrack = apps.get_model('app_name', 'urltrack')
count = 1
for row in UrlTrack.objects.all():
row.id = count
count += 1
row.save()
class Migration(migrations.Migration):
dependencies = [
('app_name', '0001_previous_migration_name'),
]
operations = [
migrations.AddField(
model_name='urltrack',
name='id',
field=models.IntegerField(),
),
migrations.RunPython(set_id),
]
Then edit models.py again and make UrlTrack unique and id primary and run makemigrations again
Im fairly new to Django. Im using Django 2.
My model:
# Create your models here.
class Trade(models.Model):
quantity = models.IntegerField()
open_price = models.FloatField()
commision = models.FloatField()
exchange_rate_usdsek = models.FloatField()
stock = models.ForeignKey(Stock, on_delete=models.CASCADE)
user = models.ForeignKey(User, related_name='trades', on_delete=models.PROTECT)
open_date = models.DateTimeField(auto_now_add=True, null=True)
def get_absolute_url(self):
return reverse('trade:detail',kwargs={'pk': self.pk})
def __str__(self):
return self.stock.name
My view
class IndexView(generic.ListView):
template_name = 'trade/index.html'
context_object_name = 'all_trades'
#
def get_queryset(self):
return Trade.objects.all()
#return Order.objects.all().prefetch_related('items')
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
return context
index.html
<h3>All stocks</h3>
<table class="table">
<thead>
<tr>
<th>Stock</th>
<th>Amount</th>
<th>Open Price</th>
<th>Commision</th>
<th>USD/SEK</th>
<th>Total sek</th>
</tr>
</thead>
{% for trade in all_trades %}
<tr>
<td>{{trade.stock.name}}</td>
<td>{{trade.quantity}}</td>
<td>{{trade.open_price}} USD</td>
<td>{{trade.commision}} SEK</td>
<td>{{trade.exchange_rate_usdsek}}</td>
<td>{{open_price * quantity * exchange_rate_usdsek}}</td>
</tr>
{% endfor %}
</table>
Now on my index.html I want to calculate and display a value.
I make a calculation like this:
total_sek = open_price * quantity * exchange_rate_usdsek
Do I have to calculate this in the views.py or in the index.html?
Also how would I do this? I searched around and found something about filters but im not sure if that is the right way to do it
The easiest way is to just define this calculation as a property on the model:
class Trade(models.Model):
# ...
#property
def total_sek(self):
return self.open_price * self.quantity * self.exchange_rate_usdsek
at which point you can simply
<td>{{ trade.total_sek }}</td>
in the template,
and trade.total_sek in Python code as required too.
I have an inline formset where I need to assign the values of a ForeignKey field sequencially and univocally to each row of the inline formset. With the select default widget of a modelchoicefield everything works but I do not want the user to select any options but to be provided with a list of the options available in the foreignfield.
My inlineformset is the following:
class ResultadoForm(forms.ModelForm):
frequencia = forms.CharField(max_length=50)
tolerancia = forms.CharField(max_length=255)
def __init__(self, *args, **kwargs):
equipamento_id = kwargs.pop('equipamento_id', None)
super (ResultadoForm, self).__init__(*args, **kwargs)
self.fields['teste'].queryset = Teste.objects.filter(equipamento=equipamento_id).order_by('grupoteste', 'numeracao')
class Meta:
model = Resultado
exclude = ['actividade']
My view that renders the form:
#login_required()
def QAView(request, equipamento_id):
form = ActividadeForm()
form1 = ResultadoForm(equipamento_id)
equipamento = Equipamento.objects.get(id=equipamento_id)
testes_list = Teste.objects.filter(equipamento=equipamento_id)
FormSet = inlineformset_factory(Actividade, Resultado, form=ResultadoForm, fields='__all__', extra=len(testes_list))
formset = FormSet(form_kwargs={'equipamento_id': equipamento_id})
context = {'equipamento_id': equipamento_id, 'data':datetime.now(), 'equipamento': equipamento, 'form': form, 'testes_list': testes_list, 'formset': formset}
template = 'SFM/Equipamento/QA.html'
return render(request, template, context)
And in my template:
{% for r in formset %}
{{ r.id }}
{% for t in r.teste.field.queryset %}
<tr>
<td>{{ t}}</td>
<td>{{ t.frequencia }}</td>
<td>{{ t.tolerancia }}</td>
<td>{{ r.conforme }}</td>
</tr>
{% endfor %}
{% endfor %}
My Resultado Model:
class Resultado(models.Model):
CONFORME_CHOICES = (
("Sim", "Sim"),
("Não", "Não"),
)
teste = models.ForeignKey(Teste, null=True, blank=True, on_delete=models.CASCADE)
conforme = models.CharField(max_length=30, choices=CONFORME_CHOICES)
actividade = models.ForeignKey(Actividade, null=True, blank=True, on_delete=models.CASCADE)
def __str__(self):
return str(self.id)
With this template I get 4 rows. I should only get two. But I have two foreign key options so I am getting the two foreign options repeated.
Is it possible to assign one and only one foreign key to each row of this inlineformset? For example for the first row automatically assign the first foreign value and to the second row the second foreign value. Please help.
Consider a model:
class TempReport(models.Model):
id = models.AutoField(primary_key=True)
cost = models.FloatField()
revenue = models.FloatField()
# Some other fields not relevant to topic
class Meta:
managed = False
db_table = 'temp_report'
unique_together = (('sale_point', 'date'), ('id', 'sale_point'),)
#property
def net_income(self):
return self.revenue - self.cost
My goal is to calculate net income = revenue - cost
The code for the template:
<tbody>
{% for repdata in reporttable %}
<tr>
<td> {{ repdata.revenue }}</td>
<td> {{ repdata.cost }}</td>
<td> {{ repdata.net_income}}</td>
</tr>
{% endfor %}
</tbody>
...and the view
def tempreport(request):
reporttable = TempReport.objects.values('id','cost','revenue')
return render_to_response('report.html',
{'reporttable': reporttable},
context_instance = RequestContext(request))
I end up with an empty net_income even if no error message is present. Any ideas why this might be caused by ?
Creating a property on the model should work. The indentation on your code is incorrect. The property should be a method of the model class, not the Meta class.
class TempReport(models.Model):
id = models.AutoField(primary_key=True)
cost = models.FloatField()
revenue = models.FloatField()
# Some other fields not relevant to topic
class Meta:
managed = False
db_table = 'temp_report'
unique_together = (('sale_point', 'date'), ('id', 'sale_point'),)
#property
def net_income(self):
return self.revenue - self.cost
In your view, don't use values(), because that will return dictionaries rather than model instances, and you won't be able to access the property.
from django.shortcuts import render
def tempreport(request):
reporttable = TempReport.objects.all()
for r in reporttable:
r.net_income = r.revenue - r.cost
return render(request, 'report.html', {'reporttable': reporttable})
Note I've also updated the view to use render instead of the obsolete render_to_response.