How to use Django JSON and GeoJSON Serializer? - python

I am relatively new to Django. I have read the documentation but I'm still having trouble getting it to work.
views.py
def getMarkers(request):
query = request.GET
zoom = query.__getitem__('zoom')
fromlat = query.__getitem__('fromlat')
tolat = query.__getitem__('tolat')
fromlng = query.__getitem__('fromlng')
tolng = query.__getitem__('tolng')
querystring = coordinate.objects.filter(lat__gt=fromlat) .filter(lat__lt = tolat).filter(lon__gt = fromlng).filter(lon__lt = tolng)
data = serialize('geojson', querystring,
geometry_field='point',
fields=('name',))
print(data)
models.py
class coordinate(models.Model):
name = models.CharField(max_length=30)
lat = models.DecimalField(max_digits=10, decimal_places=7)
lon = models.DecimalField(max_digits=10, decimal_places=7)
latlng = [lat, lon]
zoom = models.IntegerField(default=15)
def __str__(self):
return self.name
how do I use the searlizer? It's not throwing an error but I know it's not working because nothing is getting printed to the server terminal except the request

print(data) won't work. You have to do something like:
return HttpResponse(data)
Then visit the URL of that view and you'll see the result.
Update
MultiValueDictKeyError occurs if the key that you're trying to access is not in request.GET or request.POST.
To prevent this error, make sure your GET request has zoom key. For that you will need to write the URL in addressbar something like this:
/getmarkers/?zoom=val&formlat=val&somekey=val
Replace val with the value for that key.

Related

Django query filter by another dataset

I have 2 User models:
User: Default user model:
Account: Custom User model, which is an extension of the defualt user model, as I wanted to add a custom field to it called 'Status'.
The problem is that I wanted to filter the data based on the current User, so id usually do something like:
Account.objects.filter(usernmae = User).values_list('status', flat=True)
The problem is that the Account dataset doesnt have the username but they both have the same ID.
I was thinking of doing something like this:
Status = Account.objects.filter(user_id=User.objects.filter(username = user).values_list('id', flat=True)).values_list('status', flat=True)
But then i get the following error:
I imagine there is a way better way of doing it, if yall could help me out.
Views.py:
def upload_audits(request):
form = audits_form(request.POST or None, request.FILES or None)
if form.is_valid():
form.save()
form = audits_form()
obj = Csv_Audit.objects.get(activated=True)
with open(obj.file_name.path,'r') as f:
#to clear model contents before applying new data
auditsModel.objects.all().delete()
reader = csv.reader(f)
for i,row in enumerate(reader):
if i==0:
pass
else:
user = row[1] # gets data from CSV Table and returns username
Status = Account.objects.filter(user_id = request.user).values_list('status')
auditsModel.objects.create(
qs_login = user,
Status = Status,
)
obj.activated = True
obj.save()
return render(request,"backend/uploads.html",{'form':form})
Accounts.py(Model)
class Account(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
status = models.CharField(('Status'), max_length=200, default='',choices = [('Bau','Bau'),('Week 1','Week 1')])
def __str__(self):
return self.user.username
1 Answer:mahdi rahimi
I tried your method with the following code:
Status = Account.objects.filter(user__username = user).values_list('status', flat=True)
Which resulted in the following error:
And then I thought of doing this:
Status = Account.objects.filter(user = user).values_list('status', flat=True)
But i got this error:
Which actually returns the usernmae but it seems to be asking for an int?
based on my experience, you can simply join the two tables, and get what you want. roughly, it translates to this:
result = Account.objects.filter(user__username = user).values_list('status', flat=True)
or you can do two queries if you are comfortable with that.
found_user_id = User.objects.filter(username = user).values_list('id', flat = True)
result = Account.objects.filter(user_id = found_user_id).values_list('status', flat=True)
hope that helped.

Unexpected keyword argument when working with several objects

I'm trying to work with severals objects to achieve an action.
My models.py
class LogBook(models.Model):
name = models.CharField()
class LogMessage(models.Model):
logbook = models.ForeignKey(LogBook, on_delete=models.CASCADE)
class LogDone(models.Model):
logmessage = models.ForeignKey(LogMessage)
done_status = models.BooleanField(default=False)
My view :
def logmessage_done(request, logmessage_id, log_id, token ):
log = get_object_or_404(LogBook, pk=log_id)
logmessages = LogMessage.objects.filter(logbook=log)
logdone = LogDone.objects.get_or_create(logmessage=logmessages)
logdone.done_status = True
logdone.update()
My url :
"done/<int:logmessage_id>/<int:log_id>/<str:token>"
What I want to achieve :
I want to change the status of the logdone object which is link to the logmessage object but I am not sure I have access object correctly.
What error I have :
The QuerySet value for an exact lookup must be limited to one result using slicing.
Change your view like this:
def logmessage_done(request, logmessage_id, log_id, token ):
log = get_object_or_404(LogBook, pk=log_id)
logmessages = LogMessage.objects.filter(logbook=log)
for log_message in logmessages:
LogDone.objects.update_or_create(logmessage=log_message,defaults={"done_status": True})
Here , log returns a single object with id . logmessages returns a queryset with logbook = the log returned in first query. Have to use update_or_create method

How to return JSON Response correctly in joining multiple table in Django

Currently I am using Django 1.10.
For example we have the models below:
class ModelOne(models.Model):
description = models.CharField(max_length = 50)
class ModelTwo(models.Model):
description = models.CharField(max_length = 50)
m1 = models.ForeignKey( ModelOne)
class ModelThree(models.Model):
description = models.CharField(max_length = 50)
m2 = models.ForeignKey(ModelTwo)
Everytime a request is made then a JSON response is return using the code below:
from app.models import *
from django.http import HttpRequest,JsonResponse
def ViewThatReceiveRequest(request):
qs = list(ModelThree.objects.filter(description__icontains='beauty').select_related('m2__m1')
data = []
for key in qs:
temp_obj = {}
# if necessary I will convert the values before equating
temp_obj['desc3'] = key.description
temp_obj['desc2'] = key.m2.description
temp_obj['desc1'] = key.m2.m1.description
data.append(temp_obj)
return JsonResponse( {'message' : 'success', 'qs' : data }, safe = False)
Note:
- I am using Django as my back-end and ReactJs for my front-end so I only need JSON Response
My question,
- Do I need to do these for every views that receive request?
- Do we have other way to solve these simpler?
Since you only need description field from all 3 models, you can also use values method or maybe values_list of the queryset and get data.
So this new query would be
ModelThree.objects.filter(description__icontains='beauty').select_related('m2__m1).values_list('description','m2__description','m2__m1__description')
Next if you want to run some changes to your data, you can run a map method in case you want to make similar changes to all the data.
Next you can make the appropriate json and send to to client side.

django get_or_create method always results in a new record

Model
class projects(models.Model):
"""Table that holds the details of the projects."""
toiName = models.CharField(max_length=100)
toiOwner = models.CharField(max_length=50)
receiver = models.CharField(max_length=50)
manager = models.CharField(max_length=50)
toiOwnerEmail = models.EmailField(max_length=70)
receiverEmail = models.EmailField(max_length=70)
managerEmail = models.EmailField(max_length=70)
dateUpdated= models.DateTimeField(default=datetime.today())
dateCreated = models.DateTimeField(default=datetime.today())
class Meta:
db_table="projects"
View, the original code to save the model works fine, when I go ahead and edit the form in the view, I always end up with a new record.
data = model_to_dict(projects.objects.filter(toiName=pid, managerEmail=request.user)[0])
if request.method == 'POST':
form = projectsForm(request.POST)
if form.is_valid():
#form = projectsForm(request.POST, instance=projects.objects.get(toiName=pid))
#obj = projects\
obj, created = projects.objects.get_or_create\
(toiName=request.POST['toiName'],
toiOwnerEmail=request.POST['toiOwnerEmail'],
toiOwner=request.POST['toiOwner'],
manager=request.POST['manager'],
receiver=request.POST['receiver'],
receiverEmail=request.POST['receiverEmail'],
dateUpdated=datetime.now(),
dateCreated=data['dateCreated'],
managerEmail=request.user,)
Here created always results in True.
At least this dateUpdated=datetime.now() causes get_or_create to always create new record, because each time datetime.now() is different.
I believe I was using the get_or_create incorrectly, since I was only trying to update the entry.
I fixed the code in the view with:
data = model_to_dict(projects.objects.filter(toiName=pid, managerEmail=request.user)[0])
proj = projects.objects.get(toiName=pid, managerEmail=request.user)
if request.method == 'POST':
form = projectsForm(request.POST)
if form.is_valid():
proj.toiName=form.cleaned_data['toiName']
proj.toiOwnerEmail=form.cleaned_data['toiOwnerEmail']
proj.toiOwner=form.cleaned_data['toiOwner']
proj.manager=form.cleaned_data['manager']
proj.receiver=form.cleaned_data['receiver']
proj.receiverEmail=form.cleaned_data['receiverEmail']
proj.dateUpdated=datetime.now()
#proj.dateCreated=data['dateCreated']
proj.save()
additional to #user1865366 answer, projects.objects.get should be enclose it with try ... except ... like so
try:
proj = Projects.objects.get(toiName=pid,manageEmail=request.user)
except Projects.DoesNotExist :
# do something create new proj and do something with the form
...
otherwise there will be big error screen when django cannot get the object

Djangonic way to get second order DB-info in Django?

I'm messing around with my first Django site and so far it's going good. I am now facing the challenge of getting some information from the DB. My model looks like this:
class Countries(models.Model):
country = models.CharField(max_length=100)
def __unicode__(self):
return self.country
class OrganisationTypes(models.Model):
organisation_type = models.CharField(max_length=100)
def __unicode__(self):
return self.organisation_type
class Organisations(models.Model):
organisation_name = models.CharField(max_length=200)
organisation_type = models.ForeignKey(OrganisationTypes)
country_of_origin = models.ForeignKey(Countries)
def __unicode__(self):
return self.organisation_name
class Locations(models.Model):
organisation = models.ForeignKey(Organisations)
country_of_location = models.ForeignKey(Countries)
tel_nr = models.CharField(max_length=15)
address = models.CharField(max_length=100)
def __unicode__(self):
return '%s - %s - %s - %s' % (self.organisation, self.country_of_location, self.tel_nr, self.address)
I now want to display a list of locations of which I want to display the organisation_name and the country_of_origin. To achieve this I wrote the following function:
def organisation_locations(requests, organisation_id):
org = Organisations.objects.get(id=organisation_id)
location_list = Locations.objects.filter(organisation=organisation_id).order_by('country_of_location')
output = '<br />'.join([str(loc.organisation)+' from '+str(org.country_of_origin) for loc in location_list])
return HttpResponse(output)
This works correctly, but it doesn't seem like the correct way of doing this. Since the Location table has a foreign key in the Organisations table which in turn has a foreign key in the Countries table I have this vague feeling that Django can do this in one "query" or lookup.
Am I correct in this feeling, or is my way indeed the correct way of doing this? All tips are welcome!
Can't you do:
location_list = Locations.objects\
.filter(organisation=organisation_id)\
.order_by('country_of_location')
output = '<br />'.join([str(loc.organisation)+' from '+str(loc.organisation.country_of_origin) for loc in location_list])
The organisation query isn't necessary. You can access organisation like this: localization.organisation.
What is not Djangonic in your code is the response. You should have a template and do return render_to_response :)

Categories

Resources