Place players only on one team with relational table - django-models

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)

Related

Get COUNTof a many-to-one of many-to-one relationship, limit the queryset in django

Suppose I have 3 models:
class Category(models.Model):
name = models.CharField()
class Product(models.Model):
category = models.ForeignKey(Category, related_name='categories')
name = models.CharField()
class Feedback(models.Model):
product = models.ForeignKey(Product, related_name='feedbacks')
content = models.CharField()
How can I get total feedback count on every category, and get 3 first products of it too?
I want to do something like this, but it doesn't work:
Category.objects.prefetch_related(
Prefetch('categories', queryset=Product.objects.all().annotate(
feedback_count=Count('feedbacks')
)[:3])
).annotate(
product_count=Count('products'),
total_feedback_count=Count('categories__feedback_count')
)
Please help me, thanks ^^

Person - Skills many-to-many and Skill level

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).

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.

Multiple references to the same model in another model in Django

Hi I have a lot of users in my system who are classified into different types. I want to store the address details of all those users. For instance the user could be a student, a school or a franchisee. All the users here could have an address information associated with them.
from django.db import models
from django.contrib.auth.Models import User
class Address(models.Model):
user = models.OneToOneField(User)
address = models.TextField()
class Student(models.Model):
user_id = models.ForeignKey(User)
address = models.ForeignKey(Address)
class School(models.Model):
user_id = models.ForeignKey(User)
address = models.ForeignKey(Address)
contact_person_name = models.CharField(max_length=50)
In this scenario there are 2 references to the User model - one through user_id and another through address.user though they should be referring to the same instance. Is it a bad practice to have duplicate references?
I thought of leaving out the 'user' foreignkey in Address, but I think that the address can't exist without a user. How to better model this?
As you already mentioned in question duplication of same field in
a model is not a good Idea.
If these are your actual models, I would suggest you using abstract
models:
from django.db import models
from django.contrib.auth.Models import User
class Profile(models.Model):
user = models.OneToOneField(User, related_name="%(app_label)s_%(class)s_related")
address = models.TextField()
class Meta:
abstract = True
class Student(Profile):
pass
class School(Profile):
contact_person_name = models.CharField(max_length=50)
This will generate two tables: students, schools with fields
user, address and user, address, contact_person_name
respectively.

Resources