I have these two models:
class probe(models.Model):
serial=models.CharField("Serial Number",max_length=30,primary_key=True)
clientID=models.ForeignKey(organisation)
inst_date=models.DateField("Installation Date")
exp_date=models.DateField("Expiration Date",blank=True)
def save(self):
if self.exp_date is None:
self.exp_date=self.inst_date.replace(year=self.inst_date.year+1)
super(probe,self).save()
def isExpired(self):
return self.exp_date<=datetime.date.today()
isExpired.admin_order_field="exp_date"
isExpired.boolean=True
isExpired.short_description="Needs calibration"
def __str__(self):
return self.serial
class calibration(models.Model):
probe=models.ForeignKey(probe)
date=models.DateField("Date of Calibration")
isSent=models.BooleanField("Email sent?",default=False)
def __str__(self):
return str(self.date)
def save(self):
self.probe.exp_date=self.date.replace(year=self.date.year+1)
super(calibration, self).save()
When I create a calibration, I want the expiry date of the probe to update, how can I implement my models to allow that?
Try this:
from dateutil.relativedelta import relativedelta
def save(self):
self.probe.exp_date=self.date + relativedelta(years=1)
self.probe.save()
super(calibration, self).save()
Related
I have two models:
class Contrato(models.Model):
active= models.BooleanField(default=False, verbose_name="Activo?")
.....
def __str__(self,):
return str(self.id) + '- ' + str(self.forcenedor)
class Fatura(models.Model):
contrato = models.ForeignKey(Contrato, on_delete=models.CASCADE,verbose_name="Contrato")
designação = models. CharField(verbose_name="Designação",max_length=30)
..............
def __str__(self,):
return str(self.id)
When I'm adding a new "Fatura" in my django-admin , i want to only show the "Contrato" that is true on "active"
This type of filter , do i need to do in my admin file or i can do here directly on my models files? and how can i do it ?
You need to update your admin.py file
from .models import Contrato
from django.contrib import admin
class ContratoAdmin(admin.ModelAdmin):
def get_queryset(self, request):
"""Make a queryset for list of results.
"""
qs = super().get_queryset(request)
return qs.filter(active=True)
admin.site.register(Contrato, ContratoAdmin)
According to your comment you do the following.
You need to overwrite get_form method in admin.py file.
def get_form(self, request, obj=None, **kwargs):
form.base_fields['contrato'].queryset = Contrato.objects.filter(active=True)
To filter all active contracts you must use Contrato's object manager
active_contracts = Contrato.objects.filter(active=True)
def get_form(self, request, obj=None, **kwargs):
form = super(FaturaAdmin, self).get_form(request, obj=obj, **kwargs)
form.base_fields['contrato'].queryset = Contrato.objects.filter(active=True)
return form
I have a Category model. I want to make a directory for the category everytime I create a new category. I have a method in my model called create_directory.
class Category(models.Model):
category_title = models.CharField(max_length=200)
category_image = models.ImageField(upload_to="category")
category_description = models.TextField()
slug = models.SlugField(max_length=200, unique=True, default=1)
def create_directory(self):
gallery_path = os.path.abspath(
os.path.join(settings.MEDIA_ROOT, Category.slug))
if not os.path.isdir(gallery_path):
os.mkdir(gallery_path)
class Meta:
verbose_name_plural = "Categories"
unique_together = ("category_title", "slug")
def __str__(self):
return self.category_title
I want to call create_directory each time I create a category in the Admin panel.
First, I think you meant self.slug and not Category.slug. self.slug is the value of the slug field for that particular instance, while Category.slug is just an instance of the SlugField class.
You should override your model's save method to call create_directory:
class Category(models.Model):
...
def create_directory(self):
gallery_path = os.path.abspath(
os.path.join(settings.MEDIA_ROOT, self.slug))
if not os.path.isdir(gallery_path):
os.mkdir(gallery_path)
def save(self, *args, **kwargs):
if not self.pk:
self.create_directory()
super().save(*args, **kwargs)
Alternatively, you can create a signal for this:
models.py:
from django.db.models.signals import post_save
from django.dispatch import receiver
#receiver(post_save, sender=Category)
def category_post_save(sender, instance, *args, **kwargs):
gallery_path = os.path.abspath(
os.path.join(settings.MEDIA_ROOT, instance.slug))
if not os.path.isdir(gallery_path):
os.mkdir(gallery_path)
Update
If you want to remove the directory as well, you can override the delete method:
class Category(models.Model):
...
def delete(self, *args, **kwargs):
os.rmdir(os.path.join(settings.MEDIA_ROOT, self.slug))
super().delete(*args, **kwargs)
There is also a pre_delete signal that you can use.
I want to call create_directory each time I create a category in the Admin panel.
As you want to call the create_directory method when a category is created from the admin panel, you should use save_model and not save.
You might want to read Difference between save() and save_model().
Simply you can do:
def save_model(self, request, obj, form, change):
self.create_directory()
super().save_model(request, obj, form, change)
i am creating a new blog django apllication but when run it i got error
here is my code
#model.py
class Post(models.Model):
author=models.ForeignKey('auth.user',on_delete=models.CASCADE)
title=models.CharField(max_length=200)
text=models.TextField()
create_date=models.DateTimeField(default=timezone.now())
pubished_date=models.DateTimeField(blank=True,null=True)
def publish(self):
self.published_date=timezone.now()
self.save()
def approve_comments(self):
return self.comments.filter(approved_comments=True)
def get_absolute_url(self):
return reverse("post_detail",kwargs={'pk':self.pk})
def __str__(self):
return self.title
class Comment(models.Model):
post=models.ForeignKey('blog.Post',related_name='comments')
author=models.CharField(max_length=200)
test=models.TextField()
create_date=models.DateTimeField(default=timezone.now())
approved_comment=models.BooleanField(default=False)
def approve(self):
self.approved_comment=True
self.save()
def get_absolute_url(self):
return reverse('post_list')
def __str__(self):
return self.text
whenerver i run server i got this field error message. i m new to django
In your Post model you have a typo in pubished_date, it's may be published_date
I have an app that will one day allow front-end crud, which will create the slug with slugify. Right now though, all the object creation is being done in the admin area and I was wondering if there is a way to auto generate slugs while creating and saving an object from within admin?
Here is the method for slugify for the front-end; not sure if its even relevant. Thank you.
def create_slug(instance, new_slug=None):
slug = slugify(instance.title)
if new_slug is not None:
slug = new_slug
qs = Veteran.objects.filter(slug=slug).order_by('-id')
exists = qs.exists()
if exists:
new_slug = '%s-%s' % (slug, qs.first().id)
return create_slug(instance, new_slug=new_slug)
return slug
Having just used this on another answer, I have exactly the right code in my clipboard. I do exactly this for one of my models:
from django.utils.text import slugify
class Event(models.Model):
date = models.DateField()
location_title = models.TextField()
location_code = models.TextField(blank=True, null=True)
picture_url = models.URLField(blank=True, null=True, max_length=250)
event_url = models.SlugField(unique=True, max_length=250)
def __str__(self):
return self.event_url + " " + str(self.date)
def save(self, *args, **kwargs):
self.event_url = slugify(self.location_title+str(self.date))
super(Event, self).save(*args, **kwargs)
Above solutions break validation in the Django Admin interface. I suggest:
from django import forms
from django.http.request import QueryDict
from django.utils.text import slugify
from .models import Article
class ArticleForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(ArticleForm, self).__init__(*args, **kwargs)
# Ensure that data is a regular Python dictionary so we can
# modify it later.
if isinstance(self.data, QueryDict):
self.data = self.data.copy()
# We assume here that the slug is only generated once, when
# saving the object. Since they are used in URLs they should
# not change when valid.
if not self.instance.pk and self.data.get('title'):
self.data['slug'] = slugify(self.data['title'])
class Meta:
model = Article
exclude = []
I want username field automatically filled with this:
username = email[0] + str(id)
where id is the id of the user object
Is it possible ?
Thanks :)
You can use hooks to achieve this.
It would be something like this (not tested):
from django.db import models
class User(models.Model):
email = model.EmailField()
username = models.CharField(max_length=80)
def save(self):
if not self.id:
self.username = ''
super(User, self).save()
self.username = "%i%s" % (self.id, self.email)
super(User, self).save()