I am creating a webpage that is going to be used as an interface for a numerical model (controlled by a python wrapper). The idea is that the user can input parameters into a form on the page, which creates an object with all the necessary information to run the numerical model. This is my forms.py
from django import forms
from models import ChemRun
class ChemRunForm(forms.ModelForm):
class Meta:
model = ChemRun
fields = ('owner', 'title', 'times_max','temperature_min', 'temperature_max')
my models.py
from django.db import models
from django.utils import timezone
class ChemRun(models.Model):
owner = models.ForeignKey('auth.User')
title = models.CharField(max_length=200)
created_date = models.DateTimeField(default=timezone.now)
times_max = models.DecimalField(max_digits=99, decimal_places=20, null=True)
temperature_min = models.DecimalField(max_digits=99, decimal_places=20, null=True)
temperature_max = models.DecimalField(max_digits=99, decimal_places=20, null=True)
def __unicode__(self):
return self.title
and the HTML code for the form to start a new model
<header>
<h2>Start a new model</h2>
</header>
<section>
<form action='/chemrun/create/' method='post'>{% csrf_token %}
<table>
{{form.as_table}}
</table>
<input type="submit" name="submit" value="New run">
</form>
</section>
Now to my first question:
How do I catch this object which contains all the model parameters and put it into a queue from which these objects are sent to the numerical model, and I want it to be able to handle multiple cores (e.g. I can specify that X of these models are running simultaneously). How would I handle this?
Second question:
Afterwards this numerical code will create a SQLite database with the results. How can I make this webapp be alerted when models are finish and then send an email to a user to let them know their data is ready?
If you can, please explain the steps, since I am still a bit of a newbie on Django, and I prefer to understand what I am doing and why :)
Many thanks for the help!
Related
I hope someone can help me out (newbie). I am getting src(unknown) when calling an ImageField (pic) on a ForeignKey (handheld)
I see that I am able retrieve all the other values but not the models.ImageField via "cpu.handheld.pic.url", no errors in the python log. If I user for example "cpu.handheld.reg"_date works as you can see below:
HTML/JINJA:
<!-- Listing 1 -->
<div class="col-md-6 col-lg-4 mb-4">
<div class="card listing-preview">
<img class="card-img-top" src="{{ cpu.handheld.reg_date }}" alt="">
<div class="card-img-overlay">
<h2>
python log:
[12/Sep/2020 21:51:35] "GET /static/css/style.css HTTP/1.1" 200 61
Not Found: /cpus/Sept. 12, 2020, 8:25 p.m.
**[12/Sep/2020 21:51:35] "GET /cpus/Sept.%2012,%202020,%208:25%20p.m. HTTP/1.1" 404 3474**
When using "cpu.handheld.pic.url"
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
[12/Sep/2020 21:57:02] "GET /cpus/ HTTP/1.1" 200 8329
[12/Sep/2020 21:57:02] "GET /static/css/style.css HTTP/1.1" 200 61
These are the two models:
=======CPU
from django.db import models
from datetime import datetime
from django.db import models
from batt_serials.models import Battery
from serials.models import Serial
from sites.models import Site
from status.models import Status
class Cpu(models.Model):
cpu = models.CharField(max_length=100)
**handheld = models.ForeignKey(Serial, on_delete=models.DO_NOTHING)**
battery = models.ForeignKey(Battery, on_delete=models.DO_NOTHING)
site = models.ForeignKey(Site, on_delete=models.DO_NOTHING)
status = models.ForeignKey(Status, on_delete=models.DO_NOTHING)
reg_date = models.DateTimeField(default=datetime.now, blank=True)
def __str__(self):
return self.cpu
==================SERIAL
from django.db import models
from datetime import datetime
from django.db import models
from devices.models import Device
class Serial(models.Model):
serial_number = models.CharField(max_length=200)
device = models.ForeignKey(Device, on_delete=models.DO_NOTHING)
replaced = models.TextField(blank=True)
old_serial_number = models.CharField(max_length=200, blank=True)
reg_date = models.DateTimeField(default=datetime.now, blank=True)
def __str__(self):
return self.serial_number
===================Device
from django.db import models
from datetime import datetime
class Device(models.Model):
make = models.CharField(max_length=100)
model = models.CharField(max_length=100)
pic = models.ImageField(upload_to='photos/%Y/%m/%d/')
support = models.TextField(blank=True)
reg_date = models.DateTimeField(default=datetime.now, blank=True)
def __str__(self):
return self.model
Option 1: I was thing that I could reference the ForeignKey directly - something like a view for a database table.
Option 2: copy the image path value (pic) "somehow" automatically when selecting the [Device] in the [Cpu] table
you have called the DatetimeField. should call ImageField pic
<img class="card-img-top" src="{{ cpu.handheld.pic.url }}" alt="">
like this. if share views.py part it can be more clear.
I don't have enough rep to comment, so I have to answer like this for now:
Your image source, as written in your image tag, references a field that is a DateTime field. Surely that isn't what you intend?
<img class="card-img-top" src="{{ cpu.handheld.reg_date }}" alt="">
Cpu has a FK to Serial (a model that you haven't shown us in your post), which I assume has a reg-date field like your other Classes, which is likely therefore a DateTime field, not an image url.
Surely you want to reference the 'pic' field on one of your Classes (again, Serializer isn't shown here, so I don't know if it has a pic field; but your Device class does have 'pic').
Notably, your Cpu class and Device class are not connected by any FKs (or anything else), so if it's the device 'pic' field you want to display, you're going to need to rewrite your Models appropriately, and create a relation between Cpu and Device.
Thanks for the replies, I missed a level when trying to reach [pic]. I was getting unknown because there was no [pic] in the"Serial" model.
I added also the third model so the this my help some else and complete the question.
I needed to reach the "Device" model.
Cpu -> Serial -> Device[pic] so the solution is cpu.handheld.device.pic.url
p.s. Since both models have reg_date I tricked myself in think I was in the right model! :-/. I'll try and keep unique fields in the future even though some models are very similar.
Thank you m.arthur for you detailed reply!
Ciao!
I have forked the django-oscar catalogue app to alter the models being used. Not in a major way, and not in a way that would affect pulling data from the database as far as I can see. This seems to be supported by the fact the the django-oscar dashboard still works fine and lets me add and view products. My models.py from my forked app:
from django.db import models
class Collection(models.Model):
name = models.CharField(max_length=50)
prod_category = models.CharField(max_length=50)
description = models.TextField()
manufacturer = models.TextField()
num_products = models.PositiveIntegerField()
image_url = models.URLField()
from oscar.apps.catalogue.abstract_models import AbstractProduct
class Product(AbstractProduct):
collection = models.ForeignKey(Collection, on_delete=models.CASCADE, null=True)
multiplier = models.DecimalField(max_digits=2, decimal_places=1, default='2.2')
from oscar.apps.catalogue.models import *
Here is my relevant view from my views.py
def product(request):
template = loader.get_template('/home/my_app/my_site/main_page/templates/main_page/product.html')
prods = Product.objects.values_list('categories')
context={'prods': prods}
return HttpResponse(template.render(context))
I tried loading from the built in model and my forked model (commenting and uncommenting one or both), neither makes a difference:
#from forkedoscarapps.catalogue.models import Product
from oscar.core.loading import get_class, get_model
Product = get_model('catalogue', 'product')
And the code I am using in the template to display data from the view:
{% for instance in prods %}
<li><{{ instance.name }}</li>
{% endfor %}
The resulting HTML is:
<li></li>
Which shows it is reaching the for loop, but for some reason no data is returned.
There is at least one category called beds, which displays fine in the django-oscar dashboard. What have I missed in my view?
edit: When I change instance.name to just instance I get the following returned in the HTML:
(1,)
So it is somewhat working, and showing what I assume is the primary key being returned, but why is the name of the field not being returned?
Product.objects.values_list('categories') yields a list of id tuples that represent the categories associated with the products in that queryset. That's not what you want to send to the template, you want to send instances, more specifically product instances if I'm not mistaken.
Do Product.objects.all() instead, and just use {{ instance.title }} in the template according to the definition of the oscar model: https://github.com/django-oscar/django-oscar/blob/master/src/oscar/apps/catalogue/abstract_models.py and to what ever you customised over it.
I am having a tough time with following code.
{% if object.author == user.username %}
That code is not working neither giving error.
So I have articles app inside my django project. I want to make sure that if a user goes to their own post, then only they should be able to see delete and edit links (I will be placing them inside if block).
The Article model is as follows:
class Article(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('article_detail', args=[str(self.id)])
Here
{{user.username}}
{{object.author}}
both are valid django variables.
{{user.username}}
specifies username of current logged in user
{{object.author}}
specifies author of that particular post.
Please help me out to implement with comparison logic of both variables. I am using python 3.6, django 2.1 and django template language.
Your question would be easier to answer if you posted your models (and formatted your text correctly).
I presume that object.author is actually a ForeignKey to the User model. Therefore, you should compare directly with the user, not with the username attribute of the user:
{% if object.author == user %}
I'm dealing with some Django code I inherited from a dev and need to make a very simple change. In the code, there is a list of jobs displayed through a Django ListView. My problem is really simple. When I go to the page, I see the jobs sorted by date with earliest one first. I want to sort the jobs in the opposite order. I don't need any filtering, passing parameters in the URL, etc for now. Here are the relevant parts of the files:
#models.py
from django.db import models
class Job(models.Model):
created = models.DateTimeField(auto_now_add=True)
position = models.ManyToManyField(Position)
title = models.CharField(max_length=100)
#views.py
from .models import Job
class JobListView(ListView):
template_name="jobs/list.html"
model = Job
paginate_by = 10
#list.html
{% for job in object_list %}
<li class="display-list-item">
<h4><strong>{{job.title}}</strong></h4>
<ul class="list-inline job-info-list">
<span>{{job.created | timesince}} ago</span>
</ul>
</li>
{% endfor %}
#urls.py
urlpatterns = [
url('^$', views.JobListView.as_view(), name='job_list')
]
As mentioned, this causes the jobs to be displayed sorted by 'created' field. The ones created earlier are displayed first. What is the quickest way to make the ones created later display first?
first way
models.py
from django.db import models
class Job(models.Model):
created = models.DateTimeField(auto_now_add=True)
position = models.ManyToManyField(Position)
title = models.CharField(max_length=100)
class Meta:
ordering = ['-created']
second way
views.py
from .models import Job
class JobListView(ListView):
template_name="jobs/list.html"
queryset = Job.objects.order_by('-created')
paginate_by = 10
I've been advised that when it comes to updating a user I should use Django forms rather than rolling my own. As such, I've turned to Django forms but hit a bit of a wall.
A user in my system is defined, partly, as so:
#models.py
class Freelancer(AbstractBaseUser):
email = models.EmailField(primary_key=True)
first_name = models.CharField(max_length=128)
surname = models.CharField(max_length=128)
university = models.CharField(max_length=256)
verified = models.BooleanField(default=False)
biography = models.TextField(default="")
skills = models.ManyToManyField(Skill)
created_date = models.DateTimeField(default=timezone.now)
USERNAME_FIELD = 'email'
I have a URL:
#urls.py
url(r'^profile/$', views.Profile.as_view(), name="profile"),
And the view:
#views.py
class Profile(UpdateView):
model = Freelancer
fields = ['email']
template_name_suffix = '_update_form'
The problem is that I need to tell the server what Freelancer I want to update. I've tried adding (?P<pk>\d+)/ into the URL regex as I saw on a few tutorials but when I pass in the id of a Freelancer - as automatically created in the schema - it doesn't retrieve a Freelancer. Based on my model, what should I do?
I think it's a bad idea to use the email address as primary keys. What if a user changes their email address?
It might be a better idea to have unique=True for the email address, and let Django create the automatic primary key. Then including (?P<pk>\d+)/ in your url should work.
If you must use the email as the primary key, you need to change the regex from (?P<pk>\d+)/, which will only match digits, to something like
(?P<pk>[\w#.-]+)
The above might not catch all email addresses. I think Django contains a better character class, but I can't find it at the moment.
I think you are just doing it in a wrong way.
Here is what you need to do:
First of all I'd recommend you to add a pk to your model, as having email as a pk is a bad idea.
Create a url for update view
An example:
url(r'^profile/(?P<pk>[\d]+)/edit/$',
views.ProfileUpdateView.as_view(), name='edit_profile')
Create an UpdateView
An example:
class ProfileUpdateView(UpdateView):
model = Freelancer
fields = ['email']
template_name = "profiles/profile_edit.html"
Create a template for the form
An example:
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Update" />
</form>
Now you need to add this link wherever you want:
Edit
When you vist the url you will go to update page.