How can i get a object from a other function in django - django

I have two functions projectTimerStart to start the timer and projectTimerStop
i want to use the object which is created in projectTimerStart and i want to end the time when projectTimerStop , and this should be saved in a database
ps: Both the functions are not in class they are normal functions
def projectTimerStart(request, slug):
project_detail = Project.objects.get(slug=slug)
b = ProjectTimer(time_started=datetime.now(),
working_project=project_detail,
working_freelancer=request.user
)
b.save()
return HttpResponseRedirect(reverse('project_timer', kwargs=
{"slug":slug}))
def projectTimerStop(request, slug):
project_detail = Project.objects.get(slug=slug)
#i want something here super method or something
return HttpResponseRedirect(reverse('project_timer', kwargs=
{"slug": slug}))
models.py
class Project(models.Model):
project_title = models.CharField(max_length=100)
project_description = models.TextField()
created_by = models.ForeignKey(
User, on_delete=models.CASCADE, related_name='created')
assigned_to = models.ManyToManyField(
User, blank=True, related_name='assigned_by')
slug = models.SlugField()
hourly_budget = models.PositiveIntegerField(blank=True, null=True)
technologies = models.ManyToManyField(
Technologies, related_name='technologies_used')
time_posted = models.DateTimeField(auto_now_add=True)
request_id = models.ManyToManyField(
User, related_name='requested_by', blank=True)
def __str__(self):
return self.project_title
def save(self, *args, **kwargs):
self.slug = slugify(self.project_title)
super(Project, self).save(*args, **kwargs)
def get_absolute_url(self):
return reverse('project_detail', kwargs={'slug': self.slug})
def get_timer_url(self):
return reverse('project_timer', kwargs={'slug': self.slug})
def round_datetime(dt):
minutes = round((dt.minute + float(dt.second) / 60) / 15) * 15 -
dt.minute
return dt + datetime.timedelta(minutes=minutes, seconds=-dt.second)
class ProjectTimer(models.Model):
time_started = models.DateTimeField()
time_ended = models.DateTimeField(blank=True, null=True)
working_project = models.ForeignKey(Project, on_delete=models.CASCADE)
working_freelancer = models.ForeignKey(
User, on_delete=models.CASCADE, blank=True, null=True)

If each of your project objects will have one and only project timer objects, you can add project_timer = models.OneToOneField(ProjectTimer) to your Project model and access to the project timer by using project_detail.project_timer.
If not, you need to know at least one feature of that project_timer in order to fetch it from database. Or you can iterate all of your ProjectTimer objects that belongs to that Project and select the appropriate one by:
models.py
class Project(models.Model):
# Some fields
project_timers = models.ManyToManyField(ProjectTimer)
views.py
def projectTimerStop(request, slug):
project_detail = Project.objects.get(slug=slug)
for pt in project_detail.project_timers.all():
if pt.some_field == "THIS IS CORRECT TIMER":
# Here is your project_detail
print(str(pt))
return HttpResponseRedirect(reverse('project_timer', kwargs=
{"slug": slug}))

Related

"<Post:>" needs to have a value for field "id" before this many-to-many relationship can be used

When i'm trying to add a Post through django admin i get an error that the Post im trying to add needs to have a value for field id. Do you have any idea why?
now = datetime.now()
class Category(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
class Meta:
verbose_name_plural = "categories"
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=100)
excerpt = models.CharField(max_length=200)
main_image = models.ImageField()
author = models.ForeignKey(users.models.CustomUser, on_delete=models.CASCADE, related_name='blog_posts', null=True)
content = models.TextField(null=True)
created_at = models.DateTimeField(editable=False)
updated_at = models.DateTimeField(editable=False)
category = models.ManyToManyField(Category, related_name='post_category')
class Meta:
ordering = ['-created_at']
def save(self, *args, **kwargs):
if not self.id:
self.created_at = now
self.updated_at = now
def __str__(self):
return self.title
You need to make a super().save(*args, **kwargs) call. Furthermore using a constant will not work: this will assign the time when you started the server, not the current time, so:
from django.utils.timezone import now
class Post(models.Model):
# …
def save(self, *args, **kwargs):
if not self.id:
self.created_at = now()
self.updated_at = now()
super().save(*args, **kwargs)
You furthermore do not need to specify logic to update the created_at and updated_at field, you can work with auto_now_add=True [Django-doc] and auto_now=True [Django-doc]:
class Post(models.Model):
# …
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
# …
class Meta:
ordering = ['-created_at']
# no save override
def __str__(self):
return self.title

Django: using __str__ with a foreignkey in order to return an item

I am simply trying to override the str method to return something from a foreign key. A snippet of my models is as follows:
class Product(models.Model):
name = models.CharField(max_length=120)
shortened_name = models.CharField(max_length=50)
date_of_creation = models.CharField(max_length=20, null=True)
history = models.CharField(max_length=255)
price = models.DecimalField(max_digits=9, decimal_places=2)
style = models.CharField(max_length=50)
artist = models.ForeignKey(Artist, on_delete=models.SET_NULL, null=True)
image = models.ImageField(upload_to='images', null=True)
slug = models.SlugField()
def get_absolute_url(self):
return reverse('product', args=[self.slug])
def save(self, *args, **kwargs):
self.slug = slugify(self.shortened_name)
super().save(*args, **kwargs)
def get_add_to_cart_url(self):
return reverse('add_to_cart', kwargs={
'slug': self.slug
})
class ShoppingCartOrderItem(models.Model):
item = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
def __str__(self):
return self.product.name
After adding the item to my shopping cart, in the admin panel when trying to view the specific item I get an AttributeError: 'ShoppingCartOrderItem' object has no attribute 'product'. Based on my googling so far I don't see why this isn't working. I have even tried str(self.product.name) but still the same error produces. I am unsure what I am doing wrong. Any help or suggestions is greatly appreciated!

Django query only employees belonging to that company

I have 2 modules a module representing a company:
class ExternalService(models.Model):
# Fields
company_name = models.CharField(max_length=60)
address_street = models.CharField(max_length=60)
address_postcode = models.CharField(max_length=30)
address_city = models.CharField(max_length=30)
company_telephone = models.CharField(max_length=30)
company_email = models.CharField(max_length=60)
company_support_telephone = models.CharField(max_length=30)
company_support_email = models.CharField(max_length=30)
company_website = models.URLField(null=True, blank=True)
notes = models.TextField(max_length=448)
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
class Meta:
pass
def __str__(self):
return str(self.company_name)
def get_absolute_url(self):
return reverse("asset_app_ExternalService_detail", args=(self.pk,))
def get_update_url(self):
return reverse("asset_app_ExternalService_update", args=(self.pk,))
and a module representing employees:
class ExternalServiceContact(models.Model):
# Relationships
company = models.ForeignKey("asset_app.ExternalService", on_delete=models.SET_NULL, blank=True, null=True)
position = models.ForeignKey("asset_app.ExternalServicePosition", on_delete=models.SET_NULL, blank=True, null=True)
# Fields
name = models.CharField(max_length=60)
email = models.CharField(max_length=30)
cellphone = models.CharField(max_length=30)
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
class Meta:
pass
def __str__(self):
return str(self.name)
def get_absolute_url(self):
return reverse("asset_app_ExternalServiceContact_detail", args=(self.pk,))
def get_update_url(self):
return reverse("asset_app_ExternalServiceContact_update", args=(self.pk,))
In my views.py I want to get all the employees belonging to that company. So when I look at my DetailView I only get listed employees beloning to that company.
class ExternalServiceDetailView(generic.DetailView):
model = models.ExternalService
form_class = forms.ExternalServiceForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['employees'] = models.ExternalServiceContact.get(#######).order_by('name')
return context
just dont know what to insert into my get()
You can query with:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['employees'] = self.object.externalservicecontact_set.order_by('name')
return context

How to display two not associated models on one page via admin interface?

I have two models, not connected by ForeignKey. I would to display them on one page in admin interface, in the way like inlines in Django.
I can't associate PostFile with Post, because uploaded medias should be available to every Post which was and will be created in future. I have no idea what I can do if inlines are unavailable.
class Post(models.Model):
STATUS_CHOICES = (
('draft', 'Draft'),
('published', 'Published')
)
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255, unique_for_date='publish_date', blank=True)
author = models.ForeignKey(User, related_name='blog_posts', on_delete=models.CASCADE, blank=True)
content = MarkdownxField()
publish_date = models.DateTimeField(default=timezone.now)
creation_date = models.DateTimeField(auto_now_add=True)
last_update_date = models.DateField(auto_now=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
tags = models.ManyToManyField(Tag)
objects = models.Manager()
class Meta:
ordering = [
'-publish_date'
]
def __str__(self):
return self.title
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
def get_absolute_url(self):
return reverse('blog:post_detail',
args=[
self.publish_date.strftime('%Y'),
self.publish_date.strftime('%m'),
self.publish_date.strftime('%d'),
self.slug
])
#https://github.com/neutronX/django-markdownx/issues/83
def formatted_markdown(self):
return markdownify(self.content)
class PostFile(models.Model):
file_name = models.CharField(max_length=200, blank=True)
file_object = models.FileField(upload_to='post_files/')
file_upload_date = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
if not self.file_name:
self.file_name = self.file_object.name
super(PostFile, self).save(*args, **kwargs)
def file_url(self):
return self.file_object.url
def __str__(self):
return self.file_name
I would to receive in output a Post model admin page, where on the bottom I have listed all PostFile objects. This will give me easy and fast acces to PostFile-object url on media folder. I don't want each time to open new tab, and to go to PostFile model admin page to check url of object.

Django Models custom methods

is there any way to call a specific model custom method from a view? i need to subtract or increment depending on the view a field on my model, I want to create a button for each of the two options and after imputing that data update the field in my database. if so how can i go about implementing it, currently my save method is doing the two operations at once
models.py
class Items(models.Model):
nombre = models.CharField(max_length=250)
descripcion = models.CharField(max_length=250)
codigo_proveedor = models.CharField(max_length=250)
categoria = models.ForeignKey('Categorias', on_delete=models.CASCADE)
c_minima = models.PositiveIntegerField()
c_actual = models.PositiveIntegerField()
c_descuento = models.PositiveIntegerField(blank=True)
c_incremento = models.PositiveIntegerField(blank=True)
proveedor = models.ForeignKey('Proveedores', on_delete=models.CASCADE)
carrito = models.ForeignKey('Carrito', on_delete=models.CASCADE, null=True )
p_unitario = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True )
total = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
material = models.ForeignKey(Materiales, null=True, blank=True)
tipo = models.ForeignKey(Tipo, null=True, blank=True)
active = models.BooleanField()
def save(self, *args, **kwargs):
self.c_actual = self.c_actual - self.c_descuento
self.c_actual =self.c_actual + self.c_incremento
self.total = self.c_actual * self.p_unitario
super(Items, self).save(*args, **kwargs)
def __str__(self):
return '%s %s %s %s' % (self.nombre, str(self.categoria), str(self.c_actual), str(self.total))
You could use an instance method on the model e.g. exactly like the get_absolute_url().
You can add 3 methods in the model definition increment, decrement and total and write the respective logic in there.
So the view in the views.py file be something like
def some_view(request, *args, **kwargs):
#read the post data values from req
#create model instance
data = Items( #key value pairs)
#read from req to increament or decrement
if incr:
data.increament()
else:
data.decrement()
data.total()
data.save()
return render( ... )