I really need help...i ve been asking a lot of times for help and looked on google and i haven't found anything....
I want when the I click on the Table name i want to get the ID and number and obtain the details about the that table.
table_base.html
{% extends 'base.html' %}
{% block content %}
<br>
<div class="container">
<div class="jumbotron">
<h1> {{ table_name }} List</h1>
{% if list_tables %}
<table>
<thead>
<th>Id</th>
<th>Name</th>
<th>Date</th>
</thead>
{% for list in list_tables %}
<tr>
<td><pre>{{ list.id }}</pre></td>
<td><pre><a class="btn-link" href="{% url 'tables:details' list.id %}">{{ list.name }}</a></pre></td>
<td> <pre>{{ list.date }}</pre></td>
</tr>
{% endfor %}
</table>
{% else %}
<p> No Records Found</p>
{% endif %}
</div>
</div>
{% endblock %}
views.py
def table_base(request):
table_name = Crawledtables._meta.db_table
list_tables = Crawledtables.objects.order_by('id')
return render(request, 'tables/table_base.html', {'table_name': table_name,
'list_tables': list_tables})
class AboutDetail(DetailView):
model = Crawledtables
pk_url_kwarg = 'table_id'
template_name = 'tables/table_list.html'
def __init__(self, **kwargs):
super(AboutDetail, self).__init__(**kwargs)
def get_object(self):
if 'table_id' not in self.kwargs:
return Crawledtables.objects.get(id=1)
else:
return Crawledtables.objects.get(id=self.kwargs['table_id'])
class Details(ListView):
model = AllTables
template_name = 'tables/table_list.html'
context_object_name = 'details'
paginate_by = 15
queryset = AllTables.objects.all()
tables/urls.py
urlpatterns = [
url(r'^$', views.table_base, name='tables'),
url(r'^(?P<table_id>\d+)$', views.AboutDetail.as_view(), name='id-details'),
url(r'^(?P<table_id>\d+)/details$', views.Details.as_view(), name='details'),]
Basically i want to get the value of the table_id and make a new function in views where i get the table info based on what table_id i have...
If i have table_id 2 i want to the data of table_name2...
if i have table_id 3 i want to the data of table_name3...and so on.
I want this data to list it on a new template that i will create.
Something like this for the views.py:
I will get the table_id = 2 and then i use table_id to get the table name that has that id. When i get the table name..i will put it in the models.py in db_table to get that specific table details.
def details(request, table_id):
tbl_name = Crawledtables.objects.get(id=table_id)
AllTables._meta.db_table = tbl_name
query = AllTables.objects.order_by('id')
tbl_query = {'t_details': query}
return render(request, 'tables/table_list.html', context=tbl_query)
Thank you in advance
UPDATE:
I almost figure it out...but i still missing 1 more thing.
views.py
class Details(ListView):
AllTables._meta.db_table = 'table_name_1'
# AllTables._meta.db_table = 'table_name_2'
# AllTables._meta.db_table = 'table_name_3'
model = AllTables
template_name = 'tables/table_list.html'
context_object_name = 'details'
paginate_by = 15
queryset = AllTables.objects.all()
I need to switch between those 3 tables based on the table_id that i get from
views.AboutDetail or the table_base.html when the user clicks on the table_name
Something like this:
class Details(ListView):
if AboutDetail.pk_url_kwarg == 1:
AllTables._meta.db_table = 'table_name_1'
if AboutDetail.pk_url_kwarg == 2:
AllTables._meta.db_table = 'table_name_2'
if AboutDetail.pk_url_kwarg == 3:
AllTables._meta.db_table = 'table_name_3'
else:
pass
Related
I want to concatenate a string to get a product link in one of my django datatable columns.
I want a result like this:
https://www.aliexpress.com/item/1005003324927716.html
The product id is stored in my mongodb database.
This is what I tried to write in my datatable.html but i get an empty column:
{% for product in products %}
<tr>
<td>
{% with "https://www.aliexpress.com/item/"|add:{{product.productId}}|add:".html" as template %}
{% endwith %}
</td>
</tr>
{% endfor %}
Then to make it as an href link as this syntax :
<td> Click here</td>
views.py :
def datatable_view(request):
client = MongoClient("mongodb://localhost:27017/")
db = client["aliexpress"]
col = db["listproducts"]
products = col.find()
context = {'products' : products}
return render(request,'datatable.html', context)
models.py :
class Datatable(models.Model):
Title = models.CharField('Title',max_length=500),
Price = models.DecimalField('Price',decimal_places = 3, max_digits = 10000),
Currency = models.CharField('Currency',max_length=500),
Stars = models.DecimalField('Stars',decimal_places = 3 , max_digits = 10000),
Orders = models.PositiveIntegerField('Orders',max_length=500),
Shipcost = models.CharField('Shipcost',max_length=500),
Supplier = models.CharField('Supplier',max_length=500),
Productlinks = models.CharField('Productlinks',max_length=700)
I am pretty new in using django and I will be so grateful if you help me in this isuue.
Thank you !
Make it simple, add a property in your Product model
class Product(models.Model):
...
#property
def link(self):
return 'https://www.aliexpress.com/item/' + str(self.productId) + '.html'
<td> Click here</td>
UPDATE
You can make it even more simpe by doing this :
<td>Click here</td>
I would like to create a view for multiple object deletion. For this, I thought I could use a modelformset_factory.
This are my models:
class Item(models.Model):
rfid_tag = models.CharField()
asset = models.OneToOneField('Assets', default=None, null=True,
on_delete=models.SET_DEFAULT,)
date = models.DateTimeField(name='timestamp',
auto_now_add=True,)
...
class Assets(models.Model):
id = models.AutoField(db_column='Id', primary_key=True)
assettag = models.CharField(db_column='AssetTag', unique=True, max_length=10)
assettype = models.CharField(db_column='AssetType', max_length=150)
...
class Meta:
managed = False
db_table = 'Assets'
ordering = ['assettag']
def __str__(self):
return f"{self.assettag}"
def __unicode__(self):
return f"{self.assettag}"
Below is the form and formset factory:
class ItemDelete(forms.ModelForm):
asset = forms.CharField(required=True,
help_text= "Item asset tag",
max_length=16,
)
delete = forms.BooleanField(required=False,
label="Delete",
help_text='Check this box to delete the corresponding item',
)
class Meta:
model = Item
fields = ['asset']
ItemDeleteMultiple= forms.modelformset_factory(model=Item,
form=ItemDelete,
extra=0,
)
The view:
class DeleteMultipleView(generic.FormView):
template_name = *some html file*
form_class = ItemDeleteMultiple
success_url = *some url*
def form_valid(self, form):
return super().form_valid(form)
And the template:
{% extends "pages/base.html" %}
{% block title %}
<title>Delete Multiple</title>
{% endblock %}
{% block static %}
{% load static %}
{% endblock %}
{% block content %}
<h1>Delete Multiple Items</h1>
<form class="item_delete_multiple_form" action ="." method="POST"> {% csrf_token %}
<table border="2">
<tr><th colspan="3" scope="row">Select Items to Delete</th></tr>
{% for item_form in form %}
<tr>
{% if item_form.non_field_errors %}
<td>{{ item_form.non_field_errors }}</td>
{% endif %}
{% if item_form.asset.errors %}
<td>{{item_form.asset.errors}}</td>
{% endif %}
<td><label for="{{ item_form.asset.id_for_label }}">AssetTag {{forloop.counter}}:</label></td>
<td>{{item_form.asset}}</td>
{% if item_form.delete.errors %}
<td>{{item_form.delete.errors}}</td>
{% endif %}
<td>{{item_form.delete}}</td>
</tr>
{% endfor %}
</table>
</form>
{% endblock %}
{% block script %}
{% endblock %}
The template is not very easy to the eye, so here is the important part: <td>{{item_form.asset}}</td>.
The issue is the following:
If I don't add the asset = CharField() part in the ItemDelete form, the template will render what the __str__ / __unicode__ method of the Assets model will return (the assettag field) in a choice field.
If the asset field is a CharField in the form, the template will render the id of the Assets. The database entry in the Item table.
I would like to render asset.assettag in a CharField (read only text input). Is it possible to do this?
Or is there a better way to achieve the multiple delete operation, using a list of objects and a checkbox?
I have came to the following solution:
class ItemDelete(forms.ModelForm):
asset = forms.CharField(required=True,
help_text= "Item asset tag",
max_length=16,
disabled=True,
)
delete = forms.BooleanField(required=False,
label="Delete",
help_text='Check this box to delete the corresponding item',
)
def __init__(self, *args, **kwargs):
super(ItemDelete,self).__init__(*args, **kwargs)
self.initial['asset'] = Assets.objects.get(id=self.initial['asset']).assettag
class Meta:
model = Item
fields = ['asset']
Given that the input field is used just for presentation purposes (is disabled and cannot be edited), I think it will do. The downside is that it will hit the database for every object (being a formset, every object will have it's own form).
I am still open to better suggestions.
How to display only some columns of Django model in a HTML template?
And also: how do I perform a function on one of the records? (amount)?
Right now I'm displaying a whole table of model like that:
my models.py
class Tabela(models.Model):
block_id = models.CharField(max_length=64)
timestamp = models.DateTimeField()
type = models.CharField(max_length=32)
link = models.CharField(max_length=64)
link_as_account = models.CharField(max_length=100)
account = models.CharField(max_length=100)
amount = models.CharField(max_length=64)
def __str__(self):
return self.block_id
My views.py
def search_results(request):
model = Tabela
query_addresse = request.GET.get('addressee', None)
query_hash = request.GET.get('hash', None)
if not query_hash and not query_addresse and request.method == 'GET':
return render(request, 'nanosite/index.html', {})
if query_hash and request.method == 'GET':
if query_addresse:
result = Tabela.objects.filter(account=query_addresse, block_id=query_hash)
else:
result = Tabela.objects.filter(block_id=query_hash)
field_names = [f.name for f in model._meta.get_fields()]
data = [[getattr(ins, name) for name in field_names]
for ins in result]
elif query_addresse and request.method == 'GET':
result = Tabela.objects.filter(account=query_addresse)
field_names = [f.name for f in model._meta.get_fields()]
data = [[getattr(ins, name) for name in field_names]
for ins in result]
return render(request, 'nanosite/index.html', {'field_names': field_names, 'data': data})
My index.html
<div id="bottomhalf" class="table-responsive">
<table class="table table-sm table-dark table-hover">
<thead class="thead-light">
{% for head in field_names %}
<th scope="col">{{ head }}</th>
{% endfor %}
</thead>
<tbody>
{% for row in data %}
<tr scope="row">
{% for cell in row %}
<td>{{ cell }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
What I'd like to do is display only block_id, timestamp, account and amount in html. I've tried different approaches like using only the result part of views without field_names and data, but of course it didn't work.
My other question is, how can I modify the field amount and perform an operation on it to be displayed in template like amound divided by certain digit with a $ sign before it (for example if amount=1488 to be divided by 124 and displayed as '$12')?
Pass the queryset qs selecting the objects to display to the template and iterate over it to generate your table:
{% for obj in qs %}
<tr>
<td> {{obj.block_id}} </td>
<!-- etc ... -->
</tr>
{% endfor %}
Now, if you also want to pass a variable specifying the names of the fields of the object to tabulate, and in what order, you find out that the Django template engine is by design (!) incapable of doing that. You can either do what you are doing, and generate a list-of-rows in Python which you pass to the Template, or you need a Django custom template tag such as
#register.filter
def attr( obj, name):
return getattr( obj, name, '')
and then you can run an inner loop in your template
<tr>
{% for name in selected_field_names %}
<td> {{obj|attr:name}} </td>
{% endfor %}
</tr>
The answer to the second question, is to define a property on your model to return the field suitably transmogrified:
class Tabela(models.Model):
...
#property
def funny_amount(self):
val = self.amount/12.0
return f'$ {val:.2f}'
and refer to {{obj.funny_amount}} in your template
I have a Django project with a database of Song Objects that users can search through.
My models.py looks like this:
class Songs(models.Model):
title = models.CharField(max_length=100)
artist = models.CharField(max_length=100)
link = models.CharField(max_length=255, unique=True)
album = models.CharField(max_length=100)
duration = models.CharField(max_length=40) # Duration in num_secs
and my views.py looks like this:
class ResultsView(ListView):
template_name = os.path.join(APPNAME, "results.html")
model = Songs
context_object_name = 'results'
paginate_by = 60
ordering = ['title']
def get_context_data(self, **kwargs):
context = super(ResultsView, self).get_context_data(**kwargs)
context['query'] = self.request.GET.get('query')
return context
def get_queryset(self, **kwargs):
query = self.request.GET.get('query')
query_set = Songs.objects.all()
results = query_set.filter(title__icontains=query)
return list(results)
And my results.html template looks like this:
{% if results %}
<div class="container-fluid">
<div class="row">
{% for result in results %}
<div class="col-md-2 result-col">
<a data-toggle="tooltip" title="{{ result.title }}" target="_blank" href="/song/{{ result.id }}">
<div class="result-text">{{ result.title }} </div>
<div class="result-dur">{{ result.duration }}</div>
</a>
</div>
{% endfor %}
</div>
</div>
{% else %}
<h2>No Results</h2>
{% endif %}
Due to the way the data is initially stored in my DB, the duration of each song is stored as the number of seconds, ie a song that is 2 minutes long is stored with a duration of 120. However, I want to display it on the template in the format: "hh:mm:ss".
How can I modify my ResultsView class so that I can parse the duration field of all of the objects in my query_set so that they have a more readable duration?
Note: to be 100% clear, I know how to do the actual conversion, using strftime. What I don't know, is how to access the Song.duration fields in my ResultsView.
You could add a method or property to your model:
#property
def converted_time(self):
return <your converted time>
And in your template {{ result.converted_time }}
You can just use a custom template tag.
Ref
snippet
#register.filter()
def formatSeconds(s):
mins = math.floor(s / 60);
secs = math.floor(s - (mins * 60));
return "%d:%02d" % (mins, secs);
When I render the form the entire ndb model (PartModel is coming through. I'd like to have it render only the part_number property, but actual store the PartModel. I've dug through the WTForms documentation and I'm having a tough time figuring out the right way to do this.
Any thoughts? Relevant files are shown below.
new_dimension.html
<div class="control-group">
<div class="control-label">{{ form.dimension_part.label }}</div>
<div class="controls">
{{ form.dimension_part|safe }}
{% if form.dimension_part.errors %}
<ul class="errors">
{% for error in form.dimension_part.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
views.py
def list_dimensions(part_id=None):
"""List dimensions"""
if part_id is not None:
print "************Part ID is",part_id
Part = PartModel.get_by_id(part_id)
dimensions = DimensionModel.query(DimensionModel.dimension_part==Part.key).fetch()
title = "Dimensions for {}".format(Part.part_name)
else:
dimensions = DimensionModel.query() #creates Query object
title = "All Dimensions"
form = DimensionForm() #pulls in DimensionForm
if form.validate_on_submit():
dimension = DimensionModel(
dimension_part=form.dimension_part.data.key,
dimension_name=form.dimension_name.data,
dimension_value=form.dimension_value.data,
dimension_usl = form.dimension_usl.data,
dimension_lsl = form.dimension_lsl.data,
added_by=users.get_current_user()
)
try:
dimension.put()
dimension_id = dimension.key.id()
flash(u'Dimension %s successfully saved.' % dimension_id, 'success')
return redirect(url_for('list_dimensions'))
except CapabilityDisabledError:
flash(u'App Engine Datastore is currently in read-only mode.', 'info')
return redirect(url_for('list_dimensions'))
return render_template('list_dimensions.html', dimensions=dimensions, form=form,title=title) #pushes query object into template
forms.py
PartForm = model_form(PartModel, wtf.Form, field_args={
'part_name': dict(validators=[validators.Required()]),
'part_number': dict(validators=[validators.Required()])
})
models.py
class PartModel(ndb.Model):
"""Part"""
part_name = ndb.StringProperty(required=True)
part_number = ndb.FloatProperty(required=True)
added_by = ndb.UserProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
class DimensionModel(ndb.Model):
"""Dimension"""
dimension_part = ndb.KeyProperty(required=True,kind=PartModel)
dimension_name = ndb.StringProperty(required=True)
dimension_value = ndb.FloatProperty(required=True)
dimension_usl = ndb.FloatProperty(required=True)
dimension_lsl = ndb.FloatProperty(required=True)
added_by = ndb.UserProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)