Person - Skills many-to-many and Skill level - django-models

I'm trying to relate Persons, their Skills and Skill levels. My model looks like this:
class Person(models.Model):
first_name = models.CharField(max_length=200)
middle_name = models.CharField(max_length=200, blank=True)
last_name = models.CharField(max_length=200)
skills = models.ManyToManyField(Skill)
and
class Skill(models.Model):
name = models.CharField(max_length=200)
description = models.CharField(max_length=1000, blank=True)
active = models.BooleanField(default=True)
It does work (in admin) and I'm able to create a Person, add several skills etc. However, I also need the skill level information for each Skill related to each Person. Something like this:
BASIC = 'BAS'
NOVICE = 'NOV'
INTERMEDIATE = 'INT'
ADVANCED = 'ADV'
EXPERT = 'EXP'
SKILL_LEVEL_CHOICES = (
(BASIC, 'Basic knowledge'),
(NOVICE, 'Novice (Limited experience)'),
(INTERMEDIATE, 'Intermediate (Practical application)'),
(ADVANCED, 'Advanced knowledge'),
(EXPERT, 'Expert'),
)
I'm not sure what should I add to Person to have information for each skill and its level.
Thanks.

After gathering a little bit more experience on Django, I realized that it offers pretty simple solution to my problem :)
I needed two classes, SkillLevel and SkillWithSkillLevel.
class SkillLevel(models.Model):
name = models.CharField(max_length=20)
description = models.CharField(max_length=100, blank=True)
class SkillWithSkillLevel(models.Model):
skill = models.ForeignKey(Skill)
level = models.ForeignKey(SkillLevel)
person = models.ForeignKey(Person)
That's it.
It helps to have a little bit customized admin:
class SkillWithSkillLevelInline(admin.TabularInline):
model = SkillWithSkillLevel
extra = 3
And then, of course, register SkillWithSkillLevelInline within PersonAdmin, inlines = [SkillWithSkillLevelInline]
Person obviously doesn't need skills = models.ManyToManyField(Skill).

Related

Django model: Get many fields from 2 tables on same foreign key

I have 2 model classes in Django:
class Notification(models.Model):
receiver = models.ForeignKey(User, null=True, blank=True)
content = models.CharField(max_length=500)
object_id = models.IntegerField(blank=True, null=True)
type = models.TextField(max_length=200, blank=True, null=True)
Class Notification stores notification about users activity. Field "content" is like: "welcome you registered Business Course successfully", or "5ASC is your voucher code". Field type stores types of object: course, promotion.
class PaymentTransaction(models.Model):
course = models.ForeignKey(Course)
student = models.ForeignKey(User)
PAYMENT_STATUS = ( SUCCESS, FAILURE, PROCESSING)
payment_status = models.CharField(max_length=50, choices=PAYMENT_STATUS, default=PROCESSING)
In notification pop up, when he clicks to paid Course then go to Course detail page and start learning, when he clicks to unpaid Course then go to Course register page, when he clicks to promotion code then go to promotion code page
How to have a QuerySet return all fields of Notification and PaymentTransaction tables, and condition is Notification.receiver_id = PaymentTransaction.student_id .
For each Course notification, i want to get Course payment status.I did:
user = request.user
p_list = PaymentTransaction.objects.filter(student=user)
n_list = Notification.objects.filter(receiver=user).intersection(p_list)
But it did't work
I can't understand why you create the Models like this but:
I think it should be:
class Book:
title = models.CharField(max_length=500)
price = models.FloatField()
class User:
name= models.CharField(max_length=500)
something = models.CharField()
class Book_User:
user = models.ForeignKey(User)
book = models.ForeignKey(User)
detail = models.CharField()
And i what is noti for?Just show up the list?
~> it should be the list of Book_User in page of user
~> Problem solve

Place players only on one team with relational table

After going through several stackoverflows I still have yet to find something that solves this. I'm hoping it's just syntax as I'm a novice.
Admin:
from django.contrib import admin
from team_editor.models import Player, Team, TeamMembers
class PlayerInline(admin.StackedInline):
model = Player
class TMAdmin(admin.ModelAdmin):
inlines = (PlayerInline,)
# Register your models here.
admin.site.register(Team)
admin.site.register(Player)
admin.site.register(TeamMembers, TMAdmin)
Models:
class Player(models.Model):
firstName = models.CharField(max_length=30)
lastName = models.CharField(max_length=30)
class Team(models.Model):
teamName = models.CharField(max_length=30, unique=True)
class TeamMembers(models.Model):
team = models.ForeignKey(Team)
player = models.ForeignKey(Player, unique=True)
Error: class has no foreign key to class
I am using this setup since I want to view players on a team easily and change teams from one team to another (never on multiple)
Moved to many to many relation in team and dropped teammember table:
players = models.ManyToManyField(Player, blank=True, null=True)

Django models - how to create a selected_instance field from an instance in a collection

Django noob questions:
I want to create a site which allows users to share info about cars. Each car should have a collection of images, and the submitter should select one of the images to be used to represent the car on a listing page. A basic set of models is shown below:
class Manufacturer(models.Model):
name = models.CharField(max_length=255)
class ModelBrand(models.Model):
name = models.CharField(max_length=255)
class Car(models.Model):
created_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True, editable=False)
# identifying information
manufacturer = models.ForeignKey(Manufacturer)
model_brand = models.ForeignKey(ModelBrand)
model_year = models.PositiveIntegerField()
class CarImage(models.Model):
created_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True, editable=False)
car = models.ForeignKey(Car, related_name='images')
source_url = models.CharField(max_length=255, blank=True)
image = ImageField(upload_to='cars')
But how do I model the selected image? Do I put a 'selected' BooleanField on the CarImage class? And how do I configure the Car and CarImage admin classes to allow an admin site user to select and image for a car from its 'images' collection?
First, I would like to suggest you to refactor your class using an auxiliary TimeStampedClass
class TimeStampedModel(models.Model):
"""
Abstract class model that saves timestamp of creation and updating of a model.
Each model used in the project has to subclass this class.
"""
created_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True, editable=False)
class Meta:
abstract = True
ordering = ('-created_on',)
So you can use this class over your project, subclassing it.
One simple solution for your question is attach your image gallery to your car, and create one attribute that is a IntegerField that stores the picture position in the image gallery:
...
class CarImage(TimeStampedField):
source_url = models.CharField(max_length=255, blank=True)
image = ImageField(upload_to='cars')
class Car(TimeStampedModel):
image_gallery = models.ManyToManyField(CarImage)
selected_picture = models.IntegerField(default=0)
# identifying information
manufacturer = models.ForeignKey(Manufacturer)
model_brand = models.ForeignKey(ModelBrand)
model_year = models.PositiveIntegerField()
So, if selected_picture is n, you just need to get n-th picture inside image_gallery

Using GeoDjango model as an abstract class

I'm playing with GeoDjango and have some doubts. I'll really appreciate any comment and suggestion.
This is my problem. First, I've defined this (abstract) class:
from django.contrib.gis.db import models
from django.contrib.gis.geos import *
class LocatableModel(models.Model):
country = models.CharField(max_length=48, blank=True)
country_code = models.CharField(max_length=2, blank=True)
locality = models.CharField(max_length=48, blank=True)
sub_locality = models.CharField(max_length=48, blank=True)
street = models.CharField(max_length=48, blank=True)
address = models.CharField(max_length=120, blank=True)
point = models.PointField(null=True)
objects = models.GeoManager()
class Meta:
abstract = True
Second, I've defined this other 'Entity' class, which
represents a person or organization related to my site:
from django.db import models
class Entity(models.Model):
name = models.CharField(max_length=64)
slug = models.SlugField(max_length=64, unique=True)
website = models.URLField(verify_exists=False, blank=True)
email = models.EmailField(blank=True)
...
Finally, I've created a class from the previous ones:
import LocatableModel
import Entity
class Organization(Entity, LocatableModel):
timetable = models.CharField(max_length=64)
...
In my views, I'd like to find organizations near a specific point:
from django.contrib.gis.geos import Point
from django.contrib.gis.measure import D
def index(request):
pnt = Point(12.4604, 43.9420)
dic = { 'orgs': Organization.objects.filter(point__distance__lte=(pnt, D(km=7))) }
return render_to_response('index.html', dic)
But I receive the error:
"Join on field 'point' not permitted. Did you misspell 'distance' for
the lookup type?"
I think I'm doing a mess with the model 'objects' property, but I'm not sure. Any ideas?
Thanks in advance.
This error has been seen before, and claimed to be solved in this ticket 3 years ago:
https://code.djangoproject.com/ticket/9364
When I ran into this same problem, I noticed in the ticket that the query manager was set explicitly to GeoManager in the inherited model(s). So adding a line like,
class Organization(Entity, LocatableModel):
timetable = models.CharField(max_length=64)
...
objects = models.GeoManager()
...may solve the issue you're seeing, it worked for me.

Database structure linking users and media

Supposing a large number of users and a large number of videos, what would be a better way to structure the database of the following two options:
Option one --
class UserProfile(models.Model)
user = models.ForeignKey(User, unique=True)
videos = models.ManyToManyField(Video, blank=True)
class Video(models.Model)
title = models.CharField(max_length=256)
file = models.FileField(...)
Option two --
class UserProfile(models.Model)
user = models.ForeignKey(User, unique=True)
class Video(models.Model)
uploaded_by = models.ForeignKey(User)
title = models.CharField(max_length=256)
file = models.FileField(...)
Videos have nothing to do with user profiles, so the first relation is fallacious. It will also require spanning another table in order to find a user's videos. Use the second.

Resources