I am new to Django. I am working on a project that uses weather API to get the weather.Everything was working fine until models.py was made and imported city on views.py
I use ver. 1.11.13
models.py
from __future__ import unicode_literals
from django.db import models
class city(models.Model):
name = models.CharField(max_length=25)
def __str__(self):
return self.name
class Meta:
verbose_name_plural ='cities'
views.py ( Error comes at cities = city.objects.all())
import requests
from django.shortcuts import render
from .models import city
def index(request):
url= 'http://api.openweathermap.org/data/2.5/weather?q={}& units=imperial&appid=e1a2ef38103d2e572d316e38452e2acd'
city = 'Lucknow'
cities = city.objects.all()
weather_data =[]
for city in cities:
r= requests.get(url.format(city)).json()
city_weather = {
'city':city.name ,
'temperature' :r['main']['temp'],
'description' :r['weather'][0]['description'],
'icon' :r['weather'][0]['icon'] ,
}
weather_data.append(city_weather)
print(weather_data)
context = {'weather_data' : city_weather}
return render(request,'weather/weather.html', context)
Solve this issue.
For dynamic table name you can use like
table_name = 'MyTable'
model = getattr(YOURAPP.models, table_name)
model.objects.all()
In your index function, you write:
def index(request):
url= 'http://api.openweathermap.org/data/2.5/weather?q={}& units=imperial&appid=e1a2ef38103d2e572d316e38452e2acd'
city = 'Lucknow'
cities = city.objects.all()
# ...
As a result, you defined city here as a locally scoped variable, and with a string value. A quick fix is to rename the string, like:
def index(request):
url= 'http://api.openweathermap.org/data/2.5/weather?q={}& units=imperial&appid=e1a2ef38103d2e572d316e38452e2acd'
city_ = 'Lucknow'
cities = city.objects.all()
# ...
# use city_ for the string element
But nevertheless, a class typically starts with an uppercase, so I would advice to rename your class City instead of city.
Furthermore I find it weird that you defined this string, since nowehere in the view, you are supposed to use it. The url.format(..) should probably use the city.name of the City object in the queryset.
Related
I have two parameters I wish to use to get a single row from my database and use that in my template.
my url looks like:
enter code here{{ divisions }}
my view looks like this but doesn't work:
class detailView(generic.DetailView):
model = divisiondisplay
template_name = 'wondjinainfo/detail.html'
def get_queryset(self):
divisiondisplay.objects.get(divisioncode = divisioncode,freetradezone = freetradezone)
and my model looks like:
class divisiondisplay(models.Model):
freetradezone = models.ForeignKey(ftz, on_delete=models.CASCADE)
divisioncode = models.IntegerField()
bodytext = models.TextField()
imagename = models.CharField(max_length = 25)
def __str__(self):
return self.bodytext
how can I use those two parameters to select my row
I tried this change:
divisiondisplay.objects.get(divisioncode = self.kwargs['divisioncode'],freetradezone = self.kwargs['freetradezone'])
it got me new error of: Generic detail view detailView must be called with either an object pk or a slug.
because my model needed to be searched by fields other than the keys. the detail generic view was the wrong solution. I defined my own view and used it:
def divisiondisplay_detail_view(request,freetradezone, divisioncode):
try:
sometext = divisiondisplay.objects.get(divisioncode = divisioncode, freetradezone = freetradezone)
except divisiondisplay.DoesNotExist:
raise Http404('Book does not exist')
# from django.shortcuts import get_object_or_404
# book = get_object_or_404(Book, pk=primary_key)
return render(request, 'wondjinainfo/detail.html', context={'sometext': sometext})
I have to create an application that imports datas from a csv into a django model that already exists. I used the django-adaptator tool that allows to do that easily.
For exemple, I have a Sates (= "Pays") model that contains 3 fields : name, code, and nationality.
My csv :
nom;abrev;nationalite
AFGHANISTAN;AF;Afghane
AFRIQUE DU SUD;ZA;Sud-africaine
Here is my code
Models.py that already exists :
class Pays(models.Model):
pays = models.CharField(max_length=150)
codeiso3166alpha2 = models.CharField(max_length=2)
nationalite = models.CharField(max_length=50, null=True, blank=True)
maj = models.DateTimeField(auto_now=True)
class Meta:
db_table = u'Pays'
def __unicode__(self):
return self.pays
Models.py from my application :
# coding: utf-8
from django.db import models
from polyc2n.models import Pays #the model that already exists
from adaptor.model import CsvDbModel
class MyCSVDbModel(CsvDbModel):
class Meta:
exclude = ['maj']
dbModel = Pays
delimiter = ";"
has_header = True
update = {'keys': ['codeiso3166alpha2']}
My views.py:
# coding: utf-8
from django.shortcuts import render
from remplirPays.models import MyCSVDbModel
from django.http import HttpResponse
path = "pays.csv"
def DataPays(request):
MyCSVDbModel.import_data(data = open(path))
return HttpResponse("import is ok")
Here is my problem : when I do the import, the first line isn't ignored, even if I set the "has_header" attribute at True. Do you guys know why or do you know how can I resolve my problem ?
Thank you for reading
Why don't you better try using datareader and a load.py file, here i gave you a example code i use :
import csv,sys,os
import django
pathproject = "/home/yourfolder"
base_csv_filepath = "/home/yourfolder/yourcsvfile"
sys.path.append(pathproject)
os.environ['DJANGO_SETTINGS_MODULE'] = 'config.settings.local'
django.setup()
from yourapp.models import yourmodel
def load_your_data():
print ("Entering...")
csv_file = base_csv_filepath + "/yourcsvfile.csv"
dataReader = csv.reader(open(csv_file, encoding='utf-8'),delimiter=',',quotechar='"')
for row in dataReader:
if row[0] != 'ID':
yourmodel.objects.create(
field1=row[0],
field2=row[1]
)
print ("Imported correctly")
if __name__ == "__main__":
load_your_data()
EDIT: 'ID' would be the header column text, and assuming it's a 2 row data, you can of course modifiy it as you wish to cover bigger parameters.
So I have a models file:
import datetime
from django.db import models
class Organization(models.Model):
name = models.CharField(max_length=128, unique=True);
description = models.TextField(blank=True);
location = models.CharField(max_length=256, blank=True);
contact_email = models.EmailField(max_length=128, unique=True);
org_type = models.ForeignKey('OrganizationType');
created_at = models.DateTimeField(editable=False);
updated_at = models.DateTimeField();
def save(self, *args, **kwargs):
''' On save, update timestamps '''
datetime_now = datetime.datetime.now();
# If there's no ID, it's new
if not self.id:
self.created_at = datetime_now;
# Always update the modified at value
self.modified_at = datetime_now;
return super(User, self).save(*args, **kwargs);
class Meta:
app_label = 'bc';
And a view file Organization.py:
from django.shortcuts import render, redirect
from django.contrib import auth
from django.core.context_processors import csrf
from BearClubs.bc.forms.user import UserSignUpForm
from BearClubs.bc.models.organization import Organization
def directory(request):
first_50_clubs = [];
# get 50 clubs here
return render(request, 'directory.html' {'clubs': first_50_clubs});
I am really new to Django so pardon me. How do I go about getting the first 50 clubs in the first_50_clubs in the Organization.py view file?
According to the documentation, you can just use list slicing:
Use a subset of Python’s array-slicing syntax to limit your QuerySet
to a certain number of results. This is the equivalent of SQL’s LIMIT
and OFFSET clauses.
def directory(request):
first_50_clubs = Organization.objects.all()[:50]
return render(request, 'directory.html' {'clubs': first_50_clubs})
Also, you don't need to put semi-colons at the end of code lines in python.
Hope that helps.
You can get first 50 clubs in the first_50_clubs by following query :
first_50_clubs = Organization.objects.all().order_by('id')[:50]
It will fetch records when its got inserted .
If you want last inserted 50 records then just use - in order_by . like :
first_50_clubs = Organization.objects.all().order_by('-id')[:50]
say I have a model such:
class ComponentLength(models.Model):
component_name = models.CharField(max_length=155)
length1 = models.IntegerField()
length2 = models.IntegerField()
length3 = models.IntegerField()
length4 = models.IntegerField()
Now I have a form for the user to select a component, and on the next page I want to display 4 checkboxes for the various length options, which are different for different components.
What is the best way in Django to generate the form with these checkboxes based on the component name (accessible in session data) already selected by the user.
Any help much appreciated.
You could use a normal django form and change its fields upon instantiation, in the init method. Something like this:
class SecondForm(forms.Form):
def __init__(self, *args, **kwargs):
super(SecondForm, self).__init__(*args, **kwargs)
try:
#get the object, something like this:
obj_ = ComponentLength.objects.get(component_name = session.get('component_name_or_whatever_you_stored'))
except:
#handle the error case, e.g:
return
self.fields['length1'] = forms.CheckboxInput(attrs={'value' : obj_.length1 })
self.fields['length2'] = forms.CheckboxInput(attrs={'value' : obj_.length2 })
self.fields['length3'] = forms.CheckboxInput(attrs={'value' : obj_.length3 })
self.fields['length4'] = forms.CheckboxInput(attrs={'value' : obj_.length4 })
#Consider using a hidden input instead of polluting the session variables
#with form data
self.fields['component_length'] = forms.HiddenInput(attrs={'value' : obj_.pk})
The above code is not tested, but I expect it should work. Please let me know how it goes.
Form wizards is exactly what you need.
https://docs.djangoproject.com/en/1.7/ref/contrib/formtools/form-wizard/
See the example shown here https://docs.djangoproject.com/en/1.7/ref/contrib/formtools/form-wizard/#usage-of-namedurlwizardview
And how forms are defined here https://docs.djangoproject.com/en/1.7/ref/contrib/formtools/form-wizard/#conditionally-view-skip-specific-steps
I haven't tested the code below, but it should be something similar to the following:
myapp/forms.py
from django.forms import ModelForm
from myapp.models import ComponentLength
class ComponentLengthNameForm(ModelForm):
class Meta:
model = ComponentLength
fields = ['component_name',]
class ComponentLengthChoicesForm(ModelForm):
class Meta:
model = ComponentLength
fields = ['length1', 'length2', 'length3', 'length4',]
myapp/views.py
from django.contrib.formtools.wizard.views import SessionWizardView
from django.shortcuts import render_to_response
class ComponentWizard(SessionWizardView):
def done(self, form_list, **kwargs):
return render_to_response('done.html', {
'form_data': [form.cleaned_data for form in form_list],
})
myapp/urls.py
from django.conf.urls import url, patterns
from myapp.forms import ComponentLengthNameForm, ComponentLengthChoicesForm
from myapp.views import ContactWizard
named_contact_forms = (
('name', ComponentLengthNameForm),
('length-choices', ComponentLengthChoicesForm),
)
component_wizard = ComponentWizard.as_view(named_contact_forms,
url_name='component-wizard-form-step', done_step_name='finished')
urlpatterns = patterns('',
url(r'^my-form/(?P<step>.+)/$', component_wizard, name='component-wizard-form-step'),
url(r'^my-form/$', component_wizard, name='component-wizard-form'),
)
I've created a Feed subclass to export a simple feed of news
#urls.py
from django.conf.urls.defaults import *
from litenewz.feeds import NewsFeed
feeds = {
'news': NewsFeed,
}
urlpatterns = patterns(
'',
(r'^feeds/(?P<url>.*)/$',
'django.contrib.syndication.views.feed',
{'feed_dict': feeds}),
)
#feeds.py
from django.contrib.syndication.feeds import Feed
from litenewz.models import News
class NewsFeed(Feed):
title = 'example news'
link = 'http://example.net'
description = 'Latest Newz from example.'
item_author_name = '...'
item_author_email = '...'
item_author_link = 'http://example.net'
def items(self):
return News.objects.order_by('-time')[:15]
#models.py
from django.db import models
from django.utils.translation import ugettext as _
from datetime import datetime
class News(models.Model):
class Meta:
ordering = ('-time', )
verbose_name = _('News')
verbose_name_plural = _('News')
title = models.CharField(
_('Title'),
max_length=512)
time = models.DateTimeField(
_('Date and time'),
default=datetime.now
)
content = models.TextField(
_('Content'))
def __unicode__(self):
return self.title
#models.permalink
def get_absolute_url(self):
return ('home', (), {})
As you can see the Feed subclass' items() method returns the first 15 objects in News.objects.order_by('-time'):
def items(self):
return News.objects.order_by('-time')[:15]
Nevertheless, only one item is exported in the feed: hxxp://www.sshguard.net/litenewz/feeds/news/
Unfortunately, there are two objects of the News model:
>>> from litenewz.models import *
>>> News.objects.all()
[<News: Version 1.5 and timing>, <News: SSHGuard news>]
Any help?
I prefer not to switch to Django 1.2, unless this is strictly necessary to solve the issue described.
Update: the RSS returned indeed contains both the objects, but the RSS is not valid and thus readers such as Safari's are fooled:
http://validator.w3.org/feed/check.cgi?url=http://www.sshguard.net/litenewz/feeds/news/
Looks like it's not valid because you've not generated your guid correctly:
The validator says:
This feed does not validate.
line 25, column 83: guid values must not be duplicated within a feed:
... )</author><guid>http://www.sshguard.net/</guid></item></channel></rss>
The reason is that your get_absolute_url method on your News model returns the same thing for each News instance - do you have unique URLs for each News item? If so you should use that rather than:
def get_absolute_url(self):
return ('home', (), {})
The validation error appears to be from the <guid> element in each item of your feed. As far as I can tell, this is auto-generated from the get_absolute_url() method of the model, in your case the News model. Have you defined that method? If so, is it actually returning a distinct URL for each item?