jQuery UI tabs in django templates - python

I have template with many tabs (jQuery UI):
<div>
Satus: <span id="status_value"> {{ purchase.get_status_display }}</span>
Owner: <span id="admin_value"> {{ purchase.owner }}</span>
</div>
<div class="tabs">
<div class="tabs-navigation">
<ul>
<li>Purchase description</li>
<li>Purchase catalog</li>
</ul>
</div>
</div>
This is view.py, first of I render main template, than using ajax render tab, In this case purchase_info_tab, for main template I need model Purchase and for purchase_info_tab I need model Purchase and we have two identical query. Сan I avoid this somehow?
#render_to('app/purchase_view.html')
def purchase_view(request, purchase_id):
try:
purchase = Purchase.objects.get(id=purchase_id)
except Purchase.DoesNotExist:
raise Http404()
return {
'purchase': purchase,
}
#render_to('app/tabs/info_tab.html')
def purchase_info_tab(request):
purchase = #I load one model twice in one page
try:
itemsgroups = ItemsGroup.objects.filter(purchase=purchase).all()
except IndexError:
raise Http404()
return {
'itemsgroups': itemsgroups,
}

There are many ways to avoid this.
The easiest is to use sessions, as such:
#render_to('app/purchase_view.html')
def purchase_view(request, purchase_id):
try:
purchase = Purchase.objects.get(id=purchase_id)
except Purchase.DoesNotExist:
raise Http404()
else:
request.session['purchase'] = purchase
# [snip]
#render_to('app/tabs/info_tab.html')
def purchase_info_tab(request):
purchase = request.session['purchase']
# [snip]

From Django's point of view, your two views are entirely separate and you cannot share information between them without stashing it in some third location such as a URL parameter or session (remember that view methods may run even on different servers depending on how the application is deployed).
However, in the example you've given there is no need to. You don't have to retrieve your purchase object to get the ItemsGroup: you can pass an ID into your query:
itemsgroups = ItemsGroup.objects.filter(purchase__id=purchase_id).all()

Related

Django Pagination Current page in View.py

I am using Pagination in Django but using AJAX so I have to send all variables values from view to AJAX call. But For Current page there is no builtin variable available ?. As I saw official documentation. So how to Send this data already calculated in view.py ?
<span class="current">
Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
</span>
Link referenceFollowing this example
The only sensible way to do pagination/ajax/django template tags, would be to generate the entire table + current page data + table navigation etc. in the django view. I.e. move all the variables for the table from your containing page to the view for the table.
Probably a better solution is to find yourself a javascript table component and have django serve it data...
Instead of creating two different views, you can deliver the paginated content from the same view by adding a GET parameter to the url, to check for the page number and sending the ajax request to the same view. This way, it'll be easier to manage one view instead of two for the same content. And if your view does much more than generating the particular content, as you are using ajax, you can easily split the view such that one view delivers only the related content.
For example, if the url of your view is \url-to-somepage
you can send the ajax request to \url-to-somepage?page=2
Then in your template file, say template.html, include another template, say __sub_template.html for the content which will be paginated. Like,
<div>
<!--
rest of the page
-->
{% include 'templates\__sub_template.html' %}
</div>
Then in your view,
.def your_view(request):
"""
Your code here
"""
paginator = Paginator(contacts, number)
page = request.GET.get('page')
try:
result_list = paginator.page(page)
except PageNotAnInteger:
result_list = paginator.page(1)
except EmptyPage:
result_list = []
if page:
return render(request, '__sub_template.html', {'contacts': result_list})
else:
return render(request, 'template.html', {'contacts': result_list})
Use Django endless pagination http://django-endless-pagination.readthedocs.io/en/latest/twitter_pagination.html#pagination-on-scroll

How can Ajax work with a dynamic Django dropdown list?

I'm making this little web app that takes 2 addresses, calculates the distance using google maps, and calculates the gas cost based on the vehicles mpg rating. Everything is complete except for this last part that I believe would work best with AJAX.
I have 3 lists (year, make, model), and I need the list of car models to be restricted based on the year and make of the car. After selecting, I have a button that once clicked, will verify if it is a valid vehicle in the database and pull the vehicle's mpg rating to do some basic math on it.
The problem is I don't really know how to approach this problem. I've searched some inquiries the past few hours and I'm getting a lot of things related to model forms and Django choice fields which I don't want to get into if I don't have to. My idea is to just change the innerText/value, and check it against my django database.
I also came across this answer from SO:
How do I integrate Ajax with Django applications?
and am a bit confused by it. If I understand correctly, the AJAX GET request will extract data in javascript objects the same as if I visited that url as a user. Does this mean I could just create another html template and post every vehicle in the database onto that page from which I can extract info and create my dynamic lists from?
Looking for the most straightforward way to dynamically generate my lists with ajax and verify the year, make, and model with my database which will then return the car's mpg.
models.py:
class Car(models.Model):
year = models.IntegerField(default=0)
make = models.CharField(max_length=60)
model = models.CharField(max_length=60)
mpg = models.IntegerField(default=0)
def __str__(self):
return ("{0} {1} {2}".format(self.year, self.make, self.model))
views.py: (right now, it just lists every vehicle and has no way to verify the vehicle on the spot)
def index(request):
context_dic = {}
car_list = Car.objects.order_by('make')
car_list_model = Car.objects.order_by('model')
context_dic['car_list'] = car_list
context_dic['years'] = []
context_dic['makes'] = []
context_dic['models'] = []
for year in range(1995, 2016):
context_dic['years'].append(year)
for make in car_list:
if make.make not in context_dic['makes']:
context_dic['makes'].append(make.make)
else:
continue
for model in car_list_model:
if model.model not in context_dic['models']:
context_dic['models'].append(model.model)
else:
continue
return render(request, 'ConverterApp/index.html', context_dic)
html: (x3 for the make and model)
<div id="specifics">
<div class="dropdown" id="year-dropdown">
<button class="btn btn-default dropdown-toggle" type="button"
id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Year
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
{% for year in years %}
<li>{{ year }}</li>
{% endfor %}
</ul>
</div>
javascript: (just shows the value right now, but can't verify with the database)
$('#calculate').on('click', function ()
{
$(this).siblings()[0].textContent = (
document.getElementById("dropdownMenu1").textContent
+ " " + document.getElementById("dropdownMenu2").textContent
+ " " + document.getElementById("dropdownMenu3").textContent
+ " " + document.getElementById("specifics-gas").value
)
});
});
//this part changes the year, make, model to what the user selects //from the list
$('li').on('click', function () {
$(this).parent().siblings()[0].innerHTML = this.innerHTML
//console.log(this.textContent)
});
Suppose you have to populate a static list of all the brand names in a drop-down and the second dropdown is supposed to be populated based on the selection in first.
Assuming two simple Django models defining Brands and Showrooms.
Views.py
class YourView(TemplateView):
template_name = 'template.html'
def get_context_data(self, **kwargs):
brands = Brands.objects.all()
context = super(YourView, self).get_context_data(**kwargs)
context.update({'brands': brands})
return context
def get_showrooms(request, **kwargs):
brand = Brands.objects.get(id=kwargs['brand_id'])
showroom_list = list(brand.showrooms.values('id', 'name'))
return HttpResponse(simplejson.dumps(showroom_list), content_type="application/json"
HTML
<label>Select Brand</label>
<select id="brands" name="brands" class="form-control">
<option value="">Select Brand</option>
{% for brand in brands %}
<option id="{{ brand.id }}" value="{{ brand.id }}">
{{ brand.name }}
</option>
{% endfor %}
</select>
<label>Select Showrroom</label>
<div id="showroom_list">
<select name="showrooms" class="form-control">
</select>
</div
Ajax
$('select[name=brands]').change(function(){
brand_id = $(this).val();
request_url = '/sales/get_showrooms/' + brand_id + '/';
$.ajax({
url: request_url,
success: function(data){
$.each(data, function(index, text){
$('select[name=showrooms]').append(
$('<option></option>').val(index).html(text)
);
};
});
You can make the RESTful calls in request_url.
You can further populate the third dropdown based on the selection in second and so on. Also, you can access the selected option and perform the further stuff.
The chosen plugin can help you in optimizing your dropdowns.
I would go for a REST service, like Django Rest Framework, and then use jquery to autopopulate the dropdowns.
If installing a REST service is a hassle, you could write a couple of views to get the data in json format...
For instance, if you have a REST service in /myapp/api, you could populate the Cars like this:
$.ajax({
url: "/myapp/api/cars?format=json",
dataType: "json",
success: function( data ) {
var makes=[];
for (var i in data) {
car = data[i];
if (makes.indexOf(car.make) < 0){ // avoid duplicate brands
makes.push(car.make);
$('#makeselect').append($('<option>', {
value: car.id,
text: car.make
}));
}
}
}
});
Then, attach a handler when the "make" selector has changed, and populate the model and year accordingly using another REST call, like /myapp/api/cars?make=Ford
I'm not sure what you're confused about. Why would you put every car into a page? When you build a normal non-Ajax page, you pass some data - eg the slug or ID of a database object - via the URL, you query the database for that specific object, and return its data via an HTML template.
The exact same logic applies for Ajax, except that you probably don't want an HTML template; you can just return JSON, which is easy for JS to understand.

How do I pull information from a field in the admin panel?

I am currently working with Django 1.8 and Python 3. I'm using Python-social-auth to let people sign in via steam id and I'm using the SOCIAL_AUTH_STEAM_EXTRA_DATA = ['player']
setting. In the admin panel you get an field that says Extra Data. And it stores info like this
{"player": {"profileurl": "http://steamcommunity.com/profiles/76561198039465340/", "personaname": "Khailz | Daisuki <3", "avatarmedium": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/9c/9cce70b919de60669303d057446fbf563221133a_medium.jpg", "steamid": "76561198039465340", "avatarfull": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/9c/9cce70b919de60669303d057446fbf563221133a_full.jpg"}}
What I want to do is pull the avatarfull data and put it in my template when a user is logged in.
I have currently tried things like <p>{{ user.get_user_details.avatarfull }}</p> in my login.html and any other combination trying to pull this specific field. I'm not sure how to go about this, how do I pick this field out if it is backend and not in the models.py? I know I'm going about this wrong could someone point me in the right direction?
Untested, but I think the correct path is:
user.social_auth.get(
provider='steam'
).extra_data.player.avatarfull
Which isn't very convenient, so you might want to add a property to your User object:
models:
class MyUser(models.Model):
# regular stuff
#property
def get_avatar_url(self):
try:
return self.social_auth.get(
provider='steam'
).extra_data.player.avatarfull
except (UserSocialAuth.DoesNotExist, AttributeError):
return 'http://placehold.it/64x64'
templates:
<img src="{{ user.get_avatar_url }}" />
If you haven't declared a custom user object, you could just as easily create a templatetag or stand alone helper function to retrieve the avatar from an user.
templatetag:
#register.filter
def get_avatar_url(user):
try:
return user.social_auth.get(
provider='steam'
).extra_data.player.avatarfull
except (UserSocialAuth.DoesNotExist, AttributeError):
return 'http://placehold.it/64x64'
templates:
<img src="{{ user|get_avatar_url }}" />

Technique to AJAX-ify this Django app

I've been trying to develop a django app for handling bar tabs... So far I can add tabs, add products to a tab, and delete products from a tab. Now, I wanted to use AJAX on the adding/removing products from a tab, and I don't know if I needed to use a form or not... Here is what I have so far:
models.py
class Product(models.Model):
name = models.CharField(max_length='70')
price = models.FloatField()
def __unicode__(self):
return self.name
class Tab(models.Model):
number = models.IntegerField()
name = models.CharField(max_length='50')
tabdate = models.DateTimeField('date created')
consumed = models.ManyToManyField(Product, through='ConsumedRelation')
def __unicode__(self):
return self.name
class ConsumedRelation(models.Model):
tab = models.ForeignKey(Tab)
product = models.ForeignKey(Product)
count = models.PositiveIntegerField(blank=True, null=True, default=1)
def __unicode__(self):
return str(self.product)
views.py
def addproduct(request, number, product):
tab = Tab.objects.get(number=number)
product = Product.objects.get(id=product)
add = ConsumedRelation.objects.create(product=product, tab=tab, count=1)
add.save()
context = {'tab': tab, 'product': product}
return render_to_response('addproduct.html', context)
def deleteproduct(request, number, consumedid):
tab = Tab.objects.get(number=number)
ConsumedRelation.objects.filter(id=consumedid).delete()
context = {'tab': tab}
return render_to_response('deleteproduct.html', context)
urls.py
url(r'^tabs/(?P<number>[0-9].*)/delete/(?P<consumedid>[0-9].*)/$', 'barcomandas.views.deleteproduct'),
url(r'^tabs/(?P<number>[0-9].*)/add/(?P<product>[0-9].*)/$', 'barcomandas.views.addproduct'),
singletab.html
<h1>{{ tab.name }} | {{ tab.number }}</h1>
<h2>Consumed</h2>
{% for consumed in consumedlist %}
X{{ consumed }}<br/>
{% endfor %}
<div id="addproducts">
{% for product in productlist %}
<li>{{ product.name }}</li>
{% endfor %}
</div>
addproduct.html
{{ product }} added to tab {{ tab.name }}
So for example, when I add some product, I have a useless page "product added to tab" because I can't do it without some html page so I can use the view. Does that make sense?
But I don't want to make this as a form because this will be used in a 7" tablet and I'm gonna have good sized buttons for each product since the bar I'm working can get very very busy sometimes, so I need that kind of speed.
Ideally I would have ajax on everything, with a list of the current open tabs on the left, and the tab-editing on the right column, with options to add products, close tab, and etc.
So what I would want is, there's the list of the products in singletab.html, with a "X" to the side of each product. You click on the X, the product fades, and the list and everything else is updated, without reloading the page.
Do you guys see any solution to that? Sorry about my english, not my main language.
PS:
This is also my first django app, so I'm sorry for any stupid mistakes..
Would a simple jquery get on for example (/tabnumber/add/product) be enough? And how would I implement it?
I am sorry I didn't understand your question properly except below lines.
there's the list of the products in singletab.html, with a "X" to the side of each product. You click on the X, the product fades, and the list and everything else is updated, without reloading the page.
I think you can try using JQuery. Its Javascript library that makes life easier for event handling and ajaxifying of pages.
For your fade out example you can see w3 example which is good place to start learning about JQuery. you can also refer Ajax with JQuery to understand how to use Ajax with JQuery.
Hopefully, it helps you or take you a step ahead..Best of luck :-)

Google app engine ReferenceProperty relationships

I'm trying to get my models related using ReferenceProperty, but not have a huge amount of luck. I have 3 levels: Group, Topic, then Pros, and Cons. As in a Group houses many topics, and within each topic could be many Pros and Cons.
I am able to store new Groups nice and fine, but I don't have any idea how to store topics underneath these groups. I want to link from a page with a link "New topic" underneath each group, that takes them to a simple form (1 field for now). Obviously the URL will need to have some sort of reference to the id of the group or something.
Here are my models:
class Groups(db.Model):
group_user = db.UserProperty()
group_name = db.StringProperty(multiline=True)
group_date = db.DateTimeProperty(auto_now_add=True)
class Topics(db.Model):
topic_user = db.UserProperty()
topic_name = db.StringProperty(multiline=True)
topic_date = db.DateTimeProperty(auto_now_add=True)
topic_group = db.ReferenceProperty(Groups, collection_name='topics')
class Pro(db.Model):
pro_user = db.UserProperty()
pro_content = db.StringProperty(multiline=True)
pro_date = db.IntegerProperty(default=0)
pro_topic = db.ReferenceProperty(Topics, collection_name='pros')
class Con(db.Model):
con_user = db.UserProperty()
con_content = db.StringProperty(multiline=True)
con_date = db.IntegerProperty(default=0)
con_topic = db.ReferenceProperty(Topics, collection_name='cons')
And one function for the actual page I want to show the list of Groups, and then underneath their topics:
class Summary(webapp.RequestHandler):
def get(self):
groups_query = Groups.all()
groups = groups_query.fetch(1000)
template_values = {
'groups': groups,
}
path = os.path.join(os.path.dirname(__file__), 'summary.html')
self.response.out.write(template.render(path, template_values))
And finally the html:
<html>
<body>
New Group
<br>
{% for group in groups %}
<font size="24">{{ group.group_name|escape }}</font><br> by <b>{{ group.group_user }}</b> at <b>{{ group.group_date }}</b> {{ group.raw_id }}
<br>
<a href="/newtopic?id={{group.key.id}}" >New topice </a>
<br>
<blockquote>
{{ topics.topics_name }}
</blockquote>
{% endfor %}
</body>
</html>
Something that has side effects, such as altering the store (by creating a new object for example) should NOT be an HTTP GET -- GET should essentially only do "read" operations. This isn't pedantry, it's a key bit of HTTP semantics -- browsers, caches, proxies, etc, are allowed to act on GET as read-only operations (for example by caching results and not passing a request to the server if they can satisfy it from cache).
For modifications, use HTTP verbs such as POST (most popular essentially because all browsers implement it correctly) or for specialized operations PUT (to create new objects) or DELETE (to remove objects). I assume you'll be going to use POST to support a variety of browsers.
To get a POST from a browser, you need either Javascript wizardy or a plain old form with method=post -- I'll assume the latter for simplicity.
If you're using Django 1.0 (which app engine supports now), it has its own mechanisms to make, validate and accept forms based on models. Other frameworks have their own similarly advanced layers.
If you want to avoid "rich" frameworks you'll have to implement by hand templates for your HTML forms, direct them (via some kind of URL dispatching, e.g. in app.yaml) to a handler of yours implementing with a def post(self):, get the data from the request, validate it, form the new object, put it, display some acknowledgment page.
What part or parts of the procedure are unclear to you? Your question's title focuses specifically on reference properties but I'm not sure what problem they are giving you in particular -- from the text of your question you appear to be on the right tack about them.
Edit: the OP has now clarified in a comment that his problem is how to make something like:
"<a href="/newtopic?id={{group.key.id}}" >New topic </a>"
work. There's more than one way to do that. If the newtopic URL is served by a static form, the handler for the post "action" of that form could get back to that id= via the Referer: header (a notorious but unfixable mis-spelling), but that's a bit clunky and fragile. Better is to have the newtopic URI served by a handler whose def get gets the id= from the request and inserts it in the resulting form template -- for example, in a hidden input field. Have that form's template contain (among the other fields):
<INPUT TYPE=hidden NAME=thegroupid VALUE={{ theid }}> </INPUT>
put theid in the context with which you render that template, and it will be in the request that the def post of the action receiving the form finally gets.
Just to answer the question for others as you probably figured this out:
class NewTopic(webapp.RequestHandler):
def get(self):
groupId = self.request.get('group')
# either get the actual group object from the DB and initialize topic with topic_group=object as in 'Nick Johnson's answer, or do as follows
topic = Topic()
topic.name = self.request.get("topicname")
topic.reference = groupId
topic.put()
Thankyou for the reply.
Yeah I am aware of the get vs post. The class I posted was just to actually print all the Groups().
The issue I have is I'm unsure how I use the models to keep data in a sort of hierarchical fashion, with Groups > Topics > Pros/Cons.
Grabbing data is simple enough and I am using:
class NewGroupSubmit(webapp.RequestHandler):
def post(self):
group = Groups()
if users.get_current_user():
group.group_user = users.get_current_user()
group.group_name = self.request.get('groupname')
group.put()
self.redirect('/summary')
I need another function to add a new topic, that stores it within that group. So lets say a group is "Cars" for instance; the topics might be "Ferrari", "Porsche", "BMW", and then pros/cons for each topic. I realise I'm being a little vague, but it's because I'm very new to relational databasing and not quite used to the terminology.
I'm not quite sure what problem you're having. Everything you list looks fine - the ReferenceProperties are set up according to what one would expect from your dscription. The only problem I can see is that in your template, you're referring to a variable "topics", which isn't defined anywhere, and you're not iterating through the topics for a group anywhere. You can do that like this:
<html>
<body>
New Group
<br>
{% for group in groups %}
<font size="24">{{ group.group_name|escape }}</font><br> by <b>{{ group.group_user }}</b> at <b>{{ group.group_date }}</b> {{ group.raw_id }}
<br>
<a href="/newtopic?id={{group.key.id}}" >New topice </a>
<br>
Topics:
<ul>
{% for topic in group.topics %}
<li>{{topic.topic_name}}</li>
{% endfor %}
</ul>
{% endfor %}
</body>
</html>
To create a new topic, just use the constructor, passing in the required arguments:
mytopic = Topic(topic_name="foo", topic_group=somegroup)
Here, somegroup should be either a Group object, or a key for a Group object.

Categories

Resources