How to associate foreignkey data in django 3.0 - django

How do I pull all of the users and put their full name into a context that I pass to a view? My view currently pulls all of the filtered rows and I want to replace the id of the user with their full name before I pass the context to the view. This is probably very simple, but I can't seem to make it work. The field trigger_caused_by holds the id of the user that made the change that fired the trigger.
Account models.py
class User(AbstractBaseUser):
email = models.EmailField(max_length=255, unique=True, verbose_name="Email Account")
first_name = models.CharField(max_length=50, blank=True, null=True, verbose_name="First Name")
last_name = models.CharField(max_length=50, blank=True, null=True, verbose_name="Last Name")
active = models.BooleanField(default=False, verbose_name="Is Account Active")
approved = models.BooleanField(default=False, verbose_name="Is Account Approved")
readonly = models.BooleanField(default=True, verbose_name="Read Only Account")
staff = models.BooleanField(default=False, verbose_name="Staff Account")
admin = models.BooleanField(default=False, verbose_name="Admin Account")
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
def __str__(self):
return f"{self.email} - {self.last_name}, {self.first_name}"
def get_full_name(self):
if self.last_name and self.first_name:
full_name = self.last_name + ", " + self.first_name
return full_name
return self.email
def get_short_name(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
#property
def is_staff(self):
return self.staff
#property
def is_admin(self):
return self.admin
#property
def is_active(self):
return self.active
#property
def is_approved(self):
return self.approved
#property
def is_readonly(self):
return self.readonly
#property
def user_id(self):
return self.id
Historical models.py
class TCVBaseHistorical(models.Model):
opportunity_id = models.CharField(max_length=5, blank=True, verbose_name='Connected Oppporunity ID')
trigger_type = models.CharField(max_length=20, blank=True, verbose_name='Trigger Type')
new_trigger_value = models.CharField(max_length=40, blank=True, null=True, verbose_name='New Trigger Value')
datetime_of_trigger = models.DateTimeField(auto_now=False, blank=True, null=True,
verbose_name='Date/Time of Trigger')
new_date_value = models.DateField(auto_now=False, blank=True, null=True, verbose_name='New Date Value')
date_field_changed = models.CharField(max_length=10, blank=True, null=True, verbose_name="Date Field Changed")
money_field_changed = models.CharField(max_length=10, blank=True, null=True, verbose_name="Money Field Changed")
estimated = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0.0,
verbose_name='Estimated')
estimated_base = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0.0,
verbose_name='Estimated Base')
trigger_caused_by = models.CharField(max_length=5, blank=True, null=True, verbose_name='Trigger Caused By')
active = models.BooleanField(blank=True, null=True, default=True)
# def __str__(self):
# if self.trigger_type == 'tier':
# return f'{self.trigger_type} - '{self.opportunity_id} - {self.trigger_caused_by} - {self.active}'
class Meta:
verbose_name = 'Historical'
verbose_name_plural = 'Historicals'
#property
def is_active(self):
return self.active
Historical views.py
class HistoricalRoleList(ListView):
model = TCVBaseHistorical
paginate_by = 10
template_name = "Opportunity/Historical/HistRole.html"
def get_context_data(self, **kwargs):
list_historicals = super(HistoricalRoleList, self).get_context_data(**kwargs)
usersinfo = User.objects.all()
for _ in list_historicals:
caused_by = getattr(list_historicals, 'trigger_caused_by')
for _ in usersinfo:
user = getattr(usersinfo, str(User.user_id))
if caused_by == user:
list_historicals.full_name = user.get_full_name()
return list_historicals
def get_queryset(self):
qs = super().get_queryset()
cur_opp = Current_Opportunity.objects.get().current_opportunity
return qs.filter(trigger_type='role', opportunity_id=cur_opp).order_by('-datetime_of_trigger')

Related

Testing POST request throwing a KeyError in Postman

I am currently testing my POST request for the Tagging model. For this, I have tried to override the create() method. I am not so sure I have done this correctly but I tried everything I could think of. I even removed it and tried testing the POST request without overriding it.
I keep getting this error while testing with Postman:
KeyError at /api/tagging 'user'
How can I get rid of this error? What is my create() method missing?
serializers.py
class TaggingSerializer(serializers.ModelSerializer):
tag = StringRelatedField()
resource = serializers.PrimaryKeyRelatedField(read_only=True)
gameround = serializers.PrimaryKeyRelatedField(read_only=True)
user = CustomUserSerializer(required=False, read_only=True)
class Meta:
model = Tagging
fields = ('id', 'user', 'gameround', 'resource', 'tag', 'created', 'score', 'origin')
def create(self, validated_data):
"""Create and return a new tagging"""
tagging = Tagging(
user=validated_data["user"],
gameround=validated_data["gameround"],
resource=validated_data["resource"],
tag=validated_data["tag"],
created=validated_data["created"],
score=validated_data["score"],
origin=validated_data["origin"]
)
tagging.save()
return tagging
def to_representation(self, data):
data = super().to_representation(data)
return data
If I change the create method to:
def create(self, validated_data):
"""Create and return a new tagging"""
tagging = Tagging(
user=validated_data.get("user"),
gameround=validated_data.get("gameround"),
resource=validated_data.get("resource"),
tag=validated_data.get("tag"),
created=validated_data.get("created"),
score=validated_data.get("score"),
origin=validated_data.get("origin")
)
tagging.save()
return tagging
I am getting an
IntegrityError: null value in column "created" of relation "app_tagging" violates not-null constraint
DETAIL: Failing row contains (15, null, 0, , null, null, null, null).
This is my post request:
def post(self, request, *args, **kwargs):
tagging_serializer = TaggingSerializer(data=request.data)
if tagging_serializer.is_valid(raise_exception=True):
tagging_serializer.save(tagging=request.data)
return Response({"status": "success", "data": tagging_serializer.data}, status=status.HTTP_200_OK)
else:
return Response({"status": "error", "data": tagging_serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
This is the JSON I am sending
{
"user": null,
"gameround": 1,
"resource": 602,
"tag": "RTTesttaggg",
"created": "2022-12-12T15:19:49.031000Z",
"score": 0,
"origin": ""
}
models.py
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(verbose_name='email address', unique=True)
username = models.CharField(max_length=256, unique=True, blank=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
first_name = models.CharField(max_length=256, null=True)
last_name = models.CharField(max_length=256, null=True)
date_joined = models.DateTimeField(editable=False, default=timezone.now)
is_superuser = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now)
is_uploader = models.BooleanField(default=False)
first_name = models.CharField(max_length=256)
last_name = models.CharField(max_length=256)
updated_at = models.DateTimeField(auto_now=True)
REQUIRED_FIELDS = ['username']
objects = CustomUserManager()
USERNAME_FIELD = 'email'
def get_username(self):
return self.username
def __str__(self):
return f'{self.email} ({self.username})' or ''
class Resource(models.Model):
id = models.PositiveIntegerField(null=False, primary_key=True)
hash_id = models.CharField(max_length=256)
creators = models.ManyToManyField(Creator)
titles = models.ManyToManyField(Title)
created_start = models.DateField(null=True)
created_end = models.DateField(null=True)
location = models.CharField(max_length=512, null=True)
institution_source = models.CharField(max_length=512, blank=True)
institution = models.CharField(max_length=512, blank=True)
origin = models.URLField(max_length=256, null=True)
enabled = models.BooleanField(default=True)
media_type = models.CharField(max_length=256, default='picture')
objects = models.Manager()
def __str__(self):
return self.hash_id or ''
#property
def tags(self):
tags = self.taggings.values('tag').annotate(count=Count('tag'))
return tags.values('tag_id', 'tag__name', 'tag__language', 'count')
class Gameround(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True)
gamesession = models.ForeignKey(Gamesession, on_delete=models.CASCADE)
created = models.DateTimeField(editable=False)
score = models.PositiveIntegerField(default=0)
objects = models.Manager()
#property
def tags(self):
tags = self.taggings.values('tag')
return tags.values('tag_id', 'tag__name', 'tag__language', 'resource_id')
class Tag(models.Model):
name = models.CharField(max_length=256)
language = models.CharField(max_length=256)
objects = models.Manager()
def __str__(self):
return self.name or ''
#property
def tags(self):
tags = self.tagging.values('tag')
return tags.values('tag_id', 'tag__name', 'tag__language')
class Tagging(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True)
gameround = models.ForeignKey(Gameround, on_delete=models.CASCADE, related_name='taggings')
resource = models.ForeignKey(Resource, on_delete=models.CASCADE, related_name='taggings')
tag = models.ForeignKey(Tag, on_delete=models.CASCADE, related_name='tagging')
created = models.DateTimeField(editable=False)
score = models.PositiveIntegerField(default=0)
origin = models.URLField(max_length=256, blank=True, default='')
objects = models.Manager()
def __str__(self):
return str(self.tag) or ''

How can i make a Query through Many-To-Many-Relationship

I want to display the trainer for a course date. A course can have several dates and a different trainer can be used on each date. A trainer can have a different role on each course date. (Instructor, helper...)
How do I make the correct query? Are the models correct for this?
Models:
class Course_dates(models.Model):
date = models.DateField()
start = models.TimeField()
end = models.TimeField()
def __str__(self):
return str(self.id)
"""return self.date.strftime("%d.%m.%Y")"""
class Course(models.Model):
course_number = models.CharField(max_length=24, blank=True)
course_location = models.ForeignKey(Course_location, on_delete=models.CASCADE)
course_dates = models.ManyToManyField('Course_dates', through="Course_Course_dates")
def __str__(self):
return self.course_number
class Trainer_Course_Course_date_role(models.Model):
trainer = models.ForeignKey(Trainer, on_delete=models.CASCADE)
role = models.CharField(max_length=24, blank=True)
def __str__(self):
return str(self.id)
class Course_Course_dates(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE)
course_dates = models.ForeignKey(Course_dates, on_delete=models.CASCADE)
trainer = models.ForeignKey(Trainer_Course_Course_date_role, on_delete=models.CASCADE, null=True)
def __str__(self):
return str(self.id)
class Trainer(models.Model):
salutation = models.CharField(max_length=8,choices=GENDER_CHOICES)
last_names = models.CharField(max_length=56)
first_names = models.CharField(max_length=56)
date_of_birth = models.DateField()
address = models.ForeignKey(Address, on_delete=models.CASCADE)
email = models.EmailField()
phone = models.CharField(max_length=56, blank=True)
mobile = models.CharField(max_length=56, blank=True)
def __str__(self):
return self.last_names
View:
def course(request):
courses = Course.objects.all()
course_list = []
for course in courses:
sorted_date_list = course.course_dates.all().order_by('date')
course_list.append({'course': course, 'sorted_date_list': sorted_date_list })
context = { 'course_list': course_list, }
return render(request, 'kursverwaltung_tenant/course.html', context)

Django Why is one field created when I apply migrations?

There are models, why after python manage.py makemigrations is created only by 1 field in migrations, how to fix it? I tried doing manage.py migrate --fake zero, and doing the migrations again, but nothing.The app is registered in settings.
from django.db import models
from django.urls import reverse
class Category(models.Model):
image = models.ImageField(default='default.png', upload_to='category_image'),
title = models.CharField(max_length=50, db_index = True),
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('category_detail_url', kwargs={'title': self.title})
class Provider(models.Model):
name = models.CharField(max_length=50, db_index = True),
phone_number = models.CharField(max_length=12, db_index = True),
address = models.CharField(max_length=50, db_index = True),
def __str__(self):
return self.name
class Product(models.Model):
title = models.CharField(max_length=50, db_index = True),
receipt_date = models.DateTimeField(auto_now_add=True, blank=True),
quantity_stock = models.IntegerField(),
quantity_store = models.IntegerField(),
purchase_price = models.IntegerField(),
image = models.ImageField(default='default.png', upload_to='product_image'),
provider = models.ForeignKey(Provider, null = True ,related_name='to_provider',on_delete=models.CASCADE),
category = models.ForeignKey(Category, null = True ,related_name='to_category',on_delete=models.CASCADE),
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('product_detail_url', kwargs={'title': self.title})
class Sale(models.Model):
product = models.ForeignKey(Product, related_name='to_product',on_delete=models.CASCADE),
date_of_sale = models.DateTimeField(auto_now_add=True, blank=True),
quantity_goods_sold = models.IntegerField(),
retail_price = models.IntegerField(),
def __str__(self):
return self.id
Your fields should not end with a comma (,). If you add a trailing comma, it will wrap the field in a singleton tuple, and thus Django is then not able to detect the field:
from django.db import models
from django.urls import reverse
class Category(models.Model):
image = models.ImageField(default='default.png', upload_to='category_image')
title = models.CharField(max_length=50, db_index = True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('category_detail_url', kwargs={'title': self.title})
class Provider(models.Model):
name = models.CharField(max_length=50, db_index=True)
phone_number = models.CharField(max_length=12, db_index=True)
address = models.CharField(max_length=50, db_index=True)
def __str__(self):
return self.name
class Product(models.Model):
title = models.CharField(max_length=50, db_index = True)
receipt_date = models.DateTimeField(auto_now_add=True, blank=True)
quantity_stock = models.IntegerField()
quantity_store = models.IntegerField()
purchase_price = models.IntegerField()
image = models.ImageField(default='default.png', upload_to='product_image')
provider = models.ForeignKey(
Provider,
null=True,
related_name='products',
on_delete=models.CASCADE
)
category = models.ForeignKey(
Category,
null=True,
related_name='products',
on_delete=models.CASCADE
)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('product_detail_url', kwargs={'title': self.title})
class Sale(models.Model):
product = models.ForeignKey(
Product,
related_name='sales',
on_delete=models.CASCADE
)
date_of_sale = models.DateTimeField(auto_now_add=True, blank=True)
quantity_goods_sold = models.IntegerField()
retail_price = models.IntegerField()
def __str__(self):
return self.id

How do I make sure entered integer is greater than current value before updating model field?

I am using a form that saves to one model to update the most current mileage which is stored in another model. I want to make sure the mileage entered is > or = the current mileage. I havent been able to figure out the right validation or where to write the validation.
I have tried an if statement in the form_valid() of the CreateView and a save() method in the model.
Models.py
class Vehicle(models.Model):
name = models.CharField(blank=True, max_length=100)
make = models.CharField(blank=True, max_length=100)
model = models.CharField(blank=True, max_length=100)
year = models.IntegerField(blank=True, null=True)
vin = models.CharField(blank=True, max_length=17)
gvw = models.IntegerField(blank=True, null=True)
license_plate = models.CharField(blank=True, max_length=100)
purchase_date = models.DateField()
current_mileage = models.IntegerField(blank=True, null=True)
class Meta:
ordering = ['name']
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('vehicles:vehicle_detail', kwargs={'pk':self.pk})
#property
def get_current_mileage(self):
return self.current_mileage
class FuelEntry(models.Model):
vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
fuel_choices = (
('EMPTY', 'Empty'),
('1/8', '1/8'),
('1/4', '1/4'),
('1/2', '1/2'),
('3/4', '3/4'),
('FULL', 'Full'),
)
current = models.CharField(max_length=5, choices=fuel_choices)
after = models.CharField(max_length=5, choices=fuel_choices, blank=True)
gallons = models.DecimalField(decimal_places=2, max_digits=5, blank=True, default='0')
cost = models.DecimalField(decimal_places=2, max_digits=5, blank=True, default='0')
mileage = models.IntegerField(blank=False)
user = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
ordering = ['-date', 'vehicle']
def __str__(self):
return self.vehicle.name
def get_absolute_url(self):
return reverse('fuellog:entry_detail', kwargs={'pk':self.pk})
Views.py
class CreateEntry(CreateView):
model = FuelEntry
fields = ('vehicle', 'current', 'after', 'gallons', 'cost', 'mileage')
def form_valid(self,form):
self.object = form.save(commit=False)
self.object.user = self.request.user
vehicle_id = self.object.vehicle.pk
mileage = self.object.mileage
self.object.save()
current_mileage = Vehicle.objects.filter(id=vehicle_id).get('current_mileage')
if current_mileage > mileage:
raise ValidationError('Incorrect mileage reading')
Vehicle.objects.filter(id=vehicle_id).update(current_mileage=mileage)
return super().form_valid(form)
ValueError at /fuel/new
too many values to unpack (expected 2)

Auto Complete field in django

here are my models
class TimeSlots(models.Model):
start = models.TimeField(null=True, blank=True)
end = models.TimeField(null=True, blank=True)
class Meta:
ordering = ['start']
def __str__(self):
return '%s - %s' % (self.start, self.end)
class Event(models.Model):
event_date = models.DateField(null=False, blank=True)
start = models.OneToOneField(TimeSlots)
end = models.TimeField(null=True, blank=True)
available = models.BooleanField(default=True)
patient_name = models.CharField(max_length=60, null=True, blank=True)
phone_number = PhoneNumberField(blank=True, null=True)
stripePaymentId = models.CharField(max_length=150, null=True, blank=True)
stripePaid = models.BooleanField(null=False, blank=True, default=True)
key = models.UUIDField(primary_key=False, default=uuid.uuid4,
editable=False)
sites = models.ManyToManyField(Site, null=True, blank=True)
class Meta:
verbose_name = u'Scheduling'
verbose_name_plural = u'Scheduling'
def __unicode__(self):
return self.start
def get_absolute_url(self):
url = reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.model_name), args=[self.pk])
return u'%s' % (url, str(self.start))
What I want is that end value of Event Model should be auto filled by the selected Timeslot
like when I choose a start value from timeslot for the event model the end value should automatically be filled
Ok I solved it by adding a clean function in my model
def clean(self):
self.end = self.start.end
It was that simple