Dynamically generate fields+1 for model form - django

I have a model that is basically just a service report. I want this model to contain multiple punches (clock in\clock out). How do I go about doing that? When I pull up the form, I want to be able to add punches obviously.
class ServiceReportModel(models.Model):
report_number = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
site = models.ForeignKey(customers_models.SiteModel, on_delete=models.PROTECT)
request_number = models.ForeignKey(ServiceRequestModel,
on_delete=models.PROTECT,
null=True,
blank=True,
related_name='s_report_number'
)
reported_by = models.ForeignKey(main_models.MyUser, related_name='reports')
reported_date = models.DateTimeField(auto_now_add=True)
updated_by = models.ForeignKey(main_models.MyUser, blank=True, null=True, related_name='+')
updated_date = models.DateTimeField(auto_now=True)
equipment = models.ForeignKey(customers_models.EquipmentModel, on_delete=models.PROTECT)
report_reason = models.CharField(max_length=255, null=True)
time_in = models.DateTimeField(blank=True, null=True)
time_out = models.DateTimeField(blank=True, null=True)
actions_taken = models.TextField(null=False, blank=False)
recommendations = models.TextField(null=True, blank=True)
def get_absolute_url(self):
return reverse('service-report', kwargs={'pk': self.pk})
def __str__(self):
return '%s - %s, %s' % (self.site.company, self.reported_date.strftime('%d %B %Y'), self.equipment.name)
class Meta:
ordering = ['reported_date']
verbose_name = 'Service Report'
verbose_name_plural = 'Service Reports'

Related

Sum in Django Rest Framework (DRF) Serializer

Excuse me devs, i wanna ask about how to count on drf serializer, i need codes that can serialized fields plant from table A and it relations with another table B with count of them "plants_active"
Here's my code:
# Models
class TablePlants(models.Model):
plant_id = models.CharField(primary_key=True, max_length=20, unique=True)
gateway = models.ForeignKey(
TableGatewayDevice, models.DO_NOTHING, blank=True, null=True)
name = models.CharField(max_length=150, blank=True, null=True)
date = models.DateField(blank=True, null=True)
contact_person = models.CharField(max_length=70, blank=True, null=True)
contact_email = models.CharField(max_length=50, blank=True, null=True)
contact_phone = models.CharField(max_length=30, blank=True, null=True)
plant_status = models.CharField(max_length=20, blank=True, null=True)
weather_status_code = models.ForeignKey(
TableAuxWeather, models.DO_NOTHING, db_column='weather_status_code', blank=True, null=True)
timezone = models.CharField(max_length=200, blank=True, null=True)
image = models.FileField(
upload_to='plants/', validators=[file_size, validate_file_extension], null=True, blank=True)
class Meta:
db_table = 'table_plants'
def __str__(self):
return 'TablePlants[id: {id}, name: {name}]'.format(
id=self.id, name=self.name)
class PVOwner(models.Model):
pv_owner_id = models.AutoField(primary_key=True)
company = models.ForeignKey(TableCompany, on_delete=CASCADE,
blank=True, null=True, related_name="pv_owner_company")
class Meta:
db_table = 'table_pv_owner'
class TableSitePlant(models.Model):
pv_owner = models.ForeignKey(
PVOwner, on_delete=CASCADE, blank=True, null=True, related_name="pv_site_owner_plant")
site_owner = models.ForeignKey(
SiteOwner, on_delete=CASCADE, blank=True, null=True, related_name="site_owner_plant")
plant = models.ForeignKey(TablePlants, on_delete=CASCADE,
blank=True, null=True, related_name="site_plant")
class Meta:
db_table = 'table_site_plant'
# Serializer
class MainMenuSerializer(serializers.ModelSerializer):
plants_active = serializers.IntegerField(source="plant")
class Meta:
model = TableSitePlant
fields = ['plants_active']
# Views
#permission_classes([AllowAny])
class OverviewPlantsActiveView(generics.RetrieveAPIView):
queryset = TableSitePlant.objects.all().filter(plant__plant_status='offline')
serializer_class = OverviewPlantsActiveSerializer
lookup_field = 'pv_owner'
What i expecting is i can count how many plants that have status online
You can use the get method to return response as you desired.
#permission_classes([AllowAny])
class OverviewPlantsActiveView(generics.RetrieveAPIView):
queryset = TableSitePlant.objects.all().filter()
serializer_class = OverviewPlantsActiveSerializer
lookup_field = 'pv_owner'
def get(self, request):
queryset = self.get_queryset().filter(plant__plant_status='online')
return Response({
"active_plants": queryset.count(),
})

filtering objects based on boolean field state

I'm working on a project where a form is filled out. And in that form you have the is_active fields. If the user selects True, it means the account is active and if it is False, it means it is no longer active, and the user can no longer see it. Through the filters I'm trying to present only the forms with the is_active True, but I'm not able to.
Follow one of my attempts in my views:
class BookingViewSet(viewsets.ModelViewSet):
serializer_class = BookingSerializer
#queryset = Booking.objects.all()
#queryset = Booking.objects.filter(is_active="True")
#filter_backends = (filters.DjangoFilterBackend,)
#filterset_class = BookingFilter
#filterset_fields = ['is_active']
def get_queryset(self):
queryset = Booking.objects.all()
username = self.request.query_params.get('bookings')
if username is not None:
queryset = queryset.filter(is_active__username=username)
return queryset
and here are my models
class Booking(models.Model):
booking_id = models.AutoField(primary_key=True)
account = models.ForeignKey(Account, models.DO_NOTHING)
tenant = models.ForeignKey(Tenant, models.DO_NOTHING)
full_name = models.CharField(max_length=128)
email = models.CharField(max_length=256)
phone = models.CharField(max_length=256)
postal_code = models.CharField(max_length=64, null=True, blank=True)
from_city = models.CharField(max_length=256, null=True, blank=True)
to_city = models.CharField(max_length=256, null=True, blank=True)
travel_date = models.DateField()
travel_period = models.CharField(max_length=256, null=True, blank=True)
adults_travelers_count = models.SmallIntegerField()
children_travelers_count = models.SmallIntegerField()
senior_travelers_count = models.SmallIntegerField()
booking_request_description = models.TextField(blank=True, null=True)
booking_status_cd = models.CharField(max_length=10, null=True, blank=True)
locator_code = models.CharField(max_length=32, null=True, blank=True)
total_booking_price_atm = models.DecimalField(max_digits=11, decimal_places=2)
total_booking_cost_atm = models.DecimalField(max_digits=11, decimal_places=2)
payment_type_cd = models.CharField(max_length=10, null=True, blank=True)
payment_status_cd = models.CharField(max_length=10, null=True, blank=True)
payment_datetime = models.DateTimeField(blank=True, null=True)
discount_percent = models.DecimalField(max_digits=3, decimal_places=1)
discount_amount = models.DecimalField(max_digits=12, decimal_places=2)
payment_amount = models.DecimalField(max_digits=12, decimal_places=2)
voucher_file_path = models.TextField(blank=True, null=True)
receipt_file_path = models.TextField(blank=True, null=True)
invoice_file_path = models.TextField(blank=True, null=True)
modified_ts = models.DateTimeField()
modified_by = models.CharField(max_length=31)
modified_op = models.CharField(max_length=1)
created_by = models.CharField(max_length=31)
created_ts = models.DateTimeField()
is_active = models.BooleanField()
class Meta:
managed = True
db_table = 'booking'
unique_together = (("booking_id", "account", "tenant"),)
Essentially, you're correct that the filter Booking.objects.filter(is_active=True) will give you all the active bookings. If you also want to filter by username, you need to have another filter (can comma-separate in the same filter function) to filter by that. It's unclear where username lives in your models, but assuming it's on the account model:
Booking.objects.filter(is_active=True, account__username=username)
def get_queryset(self):
queryset = []
user = self.request.user
if user.is_authenticated:
bookings = Bookings.objects.all()
for i in bookings:
if i.is_active
queryset.append(i)
return queryset
This should do it!!

Django class based view, save in another model after CreateView

I have a create view (Loan_assetCreateView(generic.CreateView)) where I save if an asset is going to be loaned and when it will be returened in a model called Loan_asset(models.Model). Then I have the asset in a diffrent model Asset(model.Model). I would like to once I have saved my data in my Loan_assetCreateView(generic.CreateView) that is set the value in Asset.is_loaned to True. How can I do that?
My models.py:
class Asset(models.Model):
# Relationships
room = models.ForeignKey("asset_app.Room", on_delete=models.SET_NULL, blank=True, null=True)
model_hardware = models.ForeignKey("asset_app.Model_hardware", on_delete=models.SET_NULL, blank=True, null=True)
# Fields
name = models.CharField(max_length=30)
serial = models.CharField(max_length=30, unique=True, blank=True, null=True, default=None)
mac_address = models.CharField(max_length=30, null=True, blank=True)
purchased_date = models.DateField(null=True, blank=True)
may_be_loaned = models.BooleanField(default=False, blank=True, null=True)
is_loaned = models.BooleanField(default=False, blank=True, null=True)
missing = models.BooleanField(default=False, blank=True, null=True)
notes = HTMLField(default="")
ip = models.CharField(max_length=90, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
class Loan_asset(models.Model):
# Relationships
asset = models.ForeignKey("asset_app.Asset", on_delete=models.SET_NULL, blank=True, null=True)
loaner_type = models.ForeignKey("asset_app.Loaner_type", on_delete=models.SET_NULL, blank=True, null=True)
location = models.ForeignKey("asset_app.Locations", on_delete=models.SET_NULL, blank=True, null=True)
# Fields
loaner_name = models.CharField(max_length=60)
loaner_address = models.TextField(max_length=100, null=True, blank=True)
loaner_telephone_number = models.CharField(max_length=30)
loaner_email = models.EmailField()
loaner_quicklink = models.URLField(null=True, blank=True)
loan_date = models.DateField()
return_date = models.DateField()
notes = HTMLField(default="")
returned = models.BooleanField(default=False, blank=True, null=True)
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.loaner_name)
def get_absolute_url(self):
return reverse("asset_app_loan_asset_detail", args=(self.pk,))
def get_update_url(self):
return reverse("asset_app_loan_asset_update", args=(self.pk,))
my urls.py
`path("asset_app/loan_asset/create/", views.Loan_assetCreateView.as_view(), name="asset_app_loan_asset_create")`,
my views.py
class Loan_assetCreateView(generic.CreateView):
model = models.Loan_asset
form_class = forms.Loan_assetForm
Here are some options:
override form_valid method that's being called in post method implementation, so that after form will be validated (model instance saved), you'll be able to set the flag through foreign key/by creating Asset instance:
...
def form_valid(self, form):
self.object = form.save()
if self.object.asset:
self.object.asset.is_loaned = True
else:
self.object.asset = Asset.objects.create(is_loaned=True)
return HttpResponseRedirect(self.get_success_url())
use Django signals:
#receiver(post_save, sender=Loan_asset)
def create_transaction(sender, instance, created, **kwargs):
if created:
Asset.objects.create(is_loaned=True)
You can override the post method in your Loan_assetCreateView.
class Loan_assetCreateView(generic.CreateView):
model = models.Loan_asset
form_class = forms.Loan_assetForm
def post(request, *args, **kwargs):
response = super().post(request, *args. **kwargs)
# Do your thing
return response

Build Inline Formsets in Django Admin

So I am new to Django and I have been reading a lot of documentation to figure this out, I have a table called "Logs" that has logs of different positions (has FK of table "Position"), each position belongs to a department (has FK to table "Department") Check the image below :1
What I want to do is create a view just like this one :
2
and whenever you click on a department, it extends all the positions in it with their respective logs like this :
3
The Screenshots I have attached are my work in main app (or if you would like to call it front end), I wanted to replicate the same process in the Django Admin page, I keep seeing that I should use inlines but I can't seem to make it work, can someone help or put me in the right direction please ? much appreciated.
Here is what I have in my models.py :
from django.db import models
from django.contrib.auth.models import User
from PIL import Image
class Site(models.Model):
site = models.CharField(max_length=200, blank=True, null=True)
totalHC = models.IntegerField(blank=True, null=True)
def __str__(self):
return self.site
class Department(models.Model):
department = models.CharField(max_length=200, blank=True)
def __str__(self):
return self.department
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
site = models.ForeignKey(Site, on_delete=models.CASCADE, null=True, default=Site(id="1").site)
department = models.ForeignKey(
"Department", on_delete=models.CASCADE, null=True)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
bio = models.CharField(max_length=2000, blank=True)
skills = models.CharField(max_length=2000, blank=True)
aoi = models.CharField(max_length=2000, blank=True)
github = models.CharField(max_length=200, blank=True)
linkedin = models.CharField(max_length=200, blank=True)
def __str__(self):
return f'{self.user.username} Profile'
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.image.path)
class Grade(models.Model):
user = models.OneToOneField(Profile, on_delete=models.CASCADE)
ut1 = models.CharField(max_length=200, blank=True)
ut2 = models.CharField(max_length=200, blank=True)
ut3 = models.CharField(max_length=200, blank=True)
ut1p = models.ImageField(upload_to='plots', blank=True)
ut2p = models.ImageField(upload_to='plots', blank=True)
ut3p = models.ImageField(upload_to='plots', blank=True)
ut1pb = models.ImageField(upload_to='plots', blank=True)
ut2pb = models.ImageField(upload_to='plots', blank=True)
ut3pb = models.ImageField(upload_to='plots', blank=True)
ut12 = models.ImageField(upload_to='plots', blank=True)
ut13 = models.ImageField(upload_to='plots', blank=True)
ut23 = models.ImageField(upload_to='plots', blank=True)
class Section(models.Model):
class Meta:
verbose_name = 'Department'
verbose_name_plural = 'Departments'
section = models.CharField(max_length=200, blank=True)
def __str__(self):
return self.section
class Question(models.Model):
class Meta:
verbose_name = 'Position'
verbose_name_plural = 'Positions'
section = models.ForeignKey(
"Section", on_delete=models.CASCADE, null=True, blank=True)
question_field = models.CharField(max_length=2000, blank=True, null=True)
def __str__(self):
return self.question_field
class Answer(models.Model):
class Meta:
verbose_name = 'Log'
verbose_name_plural = 'Logs'
question = models.ForeignKey(Question, on_delete=models.CASCADE)
user = models.ForeignKey(Profile, on_delete=models.CASCADE)
answer_field = models.CharField(max_length=2000, blank=True, null=True)
def __str__(self):
return f"{self.user} answered {self.answer_field}"
class Position1(models.Model):
class Meta:
verbose_name = 'Position'
verbose_name_plural = 'Positions'
department = models.ForeignKey(
"Department", on_delete=models.CASCADE, null=True, blank=True)
position = models.CharField(max_length=200, blank=True)
jobID = models.CharField(max_length=200, blank=True)
class HCtype(models.TextChoices):
Staff = 'Staff', ('Staff')
IDL = 'IDL', ('IDL')
DL = 'DL', ('DL')
hctype = models.CharField(
max_length=5,
choices=HCtype.choices,
)
def __str__(self):
return self.position
class Log(models.Model):
position = models.ForeignKey(Position1, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
INN = models.IntegerField(blank=True, null=True)
OUT = models.IntegerField(blank=True, null=True)
date = models.CharField(max_length=200, blank=True)
internal = models.IntegerField(default=0, null=True)
class SiteHasPosition(models.Model):
date = models.CharField(max_length=200, blank=True)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
position = models.ForeignKey(Position1, on_delete=models.CASCADE)
value = models.IntegerField(blank=True, null=True)
standard = models.IntegerField(blank=True, null=True)
turn_over = models.IntegerField(blank=True, null=True)
class SiteHasDepartment(models.Model):
date = models.CharField(max_length=200, blank=True)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
department = models.ForeignKey(Department, on_delete=models.CASCADE)
value = models.IntegerField(blank=True, null=True)
class SiteKPIs(models.Model):
site = models.ForeignKey(Site, on_delete=models.CASCADE)
date = models.CharField(max_length=200, blank=True)
staff = models.IntegerField(blank=True, null=True)
dl = models.IntegerField(blank=True, null=True)
idl = models.IntegerField(blank=True, null=True)
total_hc = models.IntegerField(blank=True, null=True)
total_in = models.IntegerField(blank=True, null=True)
total_out = models.IntegerField(blank=True, null=True)
staff_rate = models.IntegerField(blank=True, null=True)
dl_rate = models.IntegerField(blank=True, null=True)
idl_rate = models.IntegerField(blank=True, null=True)
Here is how I registred them in admin.py :
admin.site.register(Profile)
admin.site.register(Log)
admin.site.register(Position1)
admin.site.register(Department)
admin.site.register(Site)
admin.site.register(SiteHasDepartment)
admin.site.register(SiteHasPosition)
I would like to have a page in admin.py where I can select a site and for that specific site display :
all the departments(when you press a dpt all the positions will expand) for each position the standardHC, attributes from the Log table (that match that position,and that site) and attributes from SiteHasPosition( that match the site and that position)
I hope I made it clearer

Two Foreign keys issue django

Hi I have this python code for django, and basically i am trying to build it so that every tourobject can have many tourbets but also i want to be able to save a certain winning tourbet as current bet but then django complains that it can't find TourBet
class TourObject(models.Model):
tourplace = models.ForeignKey(TourPlace, related_name='tourplace', verbose_name="tourplace", default=1)
title = models.CharField(max_length=155, blank=True)
description = models.TextField(blank=True)
date_created = models.DateTimeField(auto_now_add=True)
status = models.BooleanField(default=False, verbose_name="Status")
end_date = models.DateTimeField(blank=True, default=datetime.now)
current_bet = models.IntegerField(blank=True, default=0)
next_bet = models.IntegerField(blank=True, default=0)
no_auction_price = models.IntegerField(blank=True, default=1)
objects = models.Manager()
def __unicode__(self):
return self.title
def get_absolute_url(self):
return reverse("tourobjects:tourobject", kwargs={"pk": self.pk})
class RelatedTourObject(models.Manager):
def get_queryset(self):
return super(RelatedTourObject, self).get_queryset().select_related('tourobject').all()
class TourBet(models.Model):
user = models.ForeignKey(User, related_name='tourbet', verbose_name='User')
tourobject = models.ForeignKey(TourObject, related_name='tourobjectbet', verbose_name="tourobjectbet", default=1)
date_created = models.DateTimeField(blank=True, default=datetime.now)
bet_amount = models.IntegerField(blank=True, default=1)
objects = models.Manager()
related_tourobject = RelatedTourObject()
def __unicode__(self):
return str(self.bet_amount)
I think you can try this.
class TourObject(models.Model):
winning_bet = models.ForeignKey('TourBet', related_name='winning_bet')