Using a class field in another fields - python

I have a field in a class that depends on another field in the same class but I have a problem to code:
class myclass(models.Model):
nation = [('sp', 'spain'), ('fr', 'france')]
nationality = models.CharField(max_length=2, choices=nation)
first_name = models.CharField(max_length=2, choices=name)
I want to put name = [('ro', 'rodrigo'), ('ra', 'raquel')] if nation = spain and name = [('lu', 'luis'), ('ch', 'chantal')] if nation = france.
How I can do that? Thanks!

I think what you want to do is change the view that the user sees. What you have above is the underlying DB model which is the wrong place for this sort of feature.
In addition (assuming this is a web application), you will probably need to do it in Javascript, so you can change the set of allowed names as soon as the user changes the nationality field.

Related

Django collection of instances of same model

I'm new to Django
I'm currently using django 3.2.6. I want make multiple instances of route_stop model and store in SchoolRouteStop.route_graph model.I don't want use ForeignKey because i want to make somthing like like nested dict.
from django.db import models
class geo_fence(models.Model):
radius = models.FloatField()
class geo_location(models.Model):
latitude = models.FloatField()
longitude = models.FloatField()
class address(models.Model):
entity = models.fields.CharField(max_length=100)
apt_plot = models.fields.CharField(max_length=100)
street = models.fields.CharField(max_length=100)
city = models.fields.CharField(max_length=100)
state = models.fields.CharField(max_length=2) #state name in short code
zip_code = models.fields.IntegerField()
class route_stop(models.Model): # this for multiple bus stops
route_stop_id = models.fields.IntegerField()
school_id = models.fields.CharField(max_length=100)
route_number = models.fields.CharField(max_length=100)
school_route_stop_uuid = models.fields.CharField(max_length=100, primary_key=True)
registered_arrival_time = models.TimeField()
time_from_src = models.FloatField()
is_school = models.BooleanField(default=False)
geo_fence = models.ForeignKey(geo_fence, on_delete =models.CASCADE)
geo_location = models.ForeignKey(geo_location, on_delete = models.CASCADE)
address = models.ForeignKey(address, on_delete = models.CASCADE)
class SchoolRouteStop(models.Model):
school_id = models.CharField(max_length=100)
school_route_number = models.IntegerField()
route_type = models.CharField(max_length=2)
route_id = str(school_id)+'_'+str(school_route_number)+str(route_type)
route_graph= models.ForeignKey(route_stop,related_name='School', on_delete = models.CASCADE)
# Create your models here.
You have to use a ForeignKey here because you will lose all the Django ORM features and performances if you try to hack this.
Trying to use a JSONField or something else instead would also mean losing integrity constraints you would need to implement yourself, which you really want to avoid.
The way Django works is you implement your models to be stored efficiently in the database, then you use views & serializers to manipulate them.
Your models need to be refined, I really have a hard time understanding their real purpose because there are id fields everywhere (that should also probably be ForeignkeyField), and everything seems a little confusing.
For example, why is school_route_stop_uuid a CharField when UUIDField does exist?
Why is route_id not a property?
Also, make sure to follow the naming conventions in Python, it will make you code way cleaner. According to PEP 8 (https://www.python.org/dev/peps/pep-0008/#class-names):
Class names should normally use the CapWords convention.

Not sure I understand dependancy between 2 django models

I am struggling to understand django models relationship.
I have this arborescence:
A train have cars, and those cars are divided into parts. Then those parts all contains different references.
Like, for exemple, all the trains have the 6 cars, and the cars 6 parts. Each part have x reference to be associated.
I would like to use all of them in a template later on, where the user can select the train, the car and the part he worked on, then generate a table from his selections with only the references associated to the parts he selected.
It should update the train and the car (I'm trying to update a stock of elements for a company)
I dont really understand which model field give to each of them. After checking the doc, Ive done something like this but i am not convinced:
class Train(Car):
train = models.CharField(max_length=200)
id = models.CharField(primary_key='True', max_length=100)
selected = models.BooleanField()
class Meta:
abstract = True
class Car(Part):
car = models.CharField(max_length=200)
id = models.CharField(primary_key='True', max_length=100)
selected = models.BooleanField()
class Meta:
abstract = True
class Part(Reference):
part = models.CharField(max_length=200)
id = models.CharField(primary_key='True', max_length=100)
selected = models.BooleanField()
class Meta:
abstract = True
class Reference(models.Model):
reference = models.CharField(max_length=200)
id = models.CharField(primary_key='True', max_length=100)
selected = models.BooleanField()
def __str__(self):
return self.reference
Can someone please help me understand this so I can do well ? Thanks!!
1-)if you add abstract = True in your Model Meta class, your class doesn't created on database as a table. If you store data for any class, you mustn't define abstract = True.
2-)For relations, you can use models.ForeignKey . If you add a class into brackets of another class, it names: inheritance.(You can think like parent-child relation). In database management, we can use foreignkey for one-to-many relationship.
3-)In Django ORM, id field automatically generated. So you don't need to define id field.
If I understand correctly, also you want to store parts of user's selected.
So, your model can be like that:
class Train(models.Model):
name = models.CharField(max_length=200) # I think you want to save name of train
class Car(models.Model):
train = models.ForeignKey(Train,on_delete=models.Cascade)
name = models.CharField(max_length=200)
class Part(models.Model):
car = models.ForeignKey(Car,on_delete=models.Cascade)
name = models.CharField(max_length=200)
class Reference(models.Model):
part = models.ForeignKey(Part,on_delete=models.Cascade)
name = models.CharField(max_length=200)
def __str__(self):
return self.reference
#addtional table for storing user's references
class UserReference(models.Model):
user = models.ForeignKey(User,on_delete=models.Cascade)
reference = models.ForeignKey(Reference,on_delete=models.Cascade)
name = models.CharField(max_length=200)
With this definitions, you can store user's definition on UserReference table. And with Django Orm, you can access train object from UserReferenceObject.
#user_reference: UserReference object like that result of UserReference.objects.first()
user_reference.reference.part.car.train.name

Django Models design: many-to-many relationship with specific needs

I am in the process of designing a couple of new models for my django app and this is what I need:
class Bookmaker(models.Model):
name = models.CharField(max_length=50)
accepted_countries = ?
restricted_countries = ?
class Country(models.Model):
name = models.CharField(max_length=50)
bookmakers = ?
So I need a model Bookmaker and a model Country and they need to be related, BUT every bookmaker should have a list of countries that are accepted and a list of countries that are excluded.
The question marks are both in the Country and in the Bookmaker models as I'm not sure which way the relation should go.
Not sure if I'm on the right path, but I'm thinking that I need a couple of many-to-many relationships.. And, which is the right way (if any) to use the same Country model (those will be different instances) in both accepted_countries and restricted_countries?
Thanks.
You should use two many to many relations with related_name to separate them:
class Bookmaker(models.Model):
name = models.CharField(max_length=50)
accepted_countries = models.ManyToManyField(Country, related_name="accepted_for")
restricted_countries = models.ManyToManyField(Country, related_name="restricted_for")
You can then use the reverse relation as:
bookmakers_for_which_county_is_accepted = Country.objects.values('accepted_for').distinct()
bookmakers_for_which_county_is_restricted = Country.objects.values('restricted_for').distinct()
docs
You need indeed some many to many:
class Bookmaker(models.Model):
name = models.CharField(max_length=50)
accepted_countries = models.ManyToMany('Country',related_name='accepted')
restricted_countries = models.ManyToMany('Country', related_name= 'restricted')
class Country(models.Model):
name = models.CharField(max_length=50)
bookmakers = models.ManyToMany(Bookmaker)
Then if you create a form to edit a bookmaker you will be abble to add the name, the accepted and restricted countries:
forms.py
class BookmakerForm(models.ModelForm):
class Meta:
model = Bookmaker
fields = ['name', 'accepted_countries', 'restricted_countries']
#for having a better default display you can change the widget:
self __init__(self, *args, **kwargs):
super(BookmakerForm, self).__init__(*args, **kwargs)
self.fields['accepted_countries'].widget = CheckboxSelectMultiple()
self.fields['restricted_countries'].widget = CheckboxSelectMultiple()
In the view by default if you just need to check if form.is_valid() and save. django modelform will manage the intermediary step for you.
The bookmakers field in Country allows you to retrieve all the bookmaker associated to a country without having to check in both accepted and restricted (it's more for convenience).
But you will need to add the bookmaker to that list on you view like:
class CreateBookmakerView(CreateView):
model = Bookmaker
form_class = BookmakerForm
success_url = reverse_lazy('your success url name here')
def form_valid(self,form):
bookmaker = form.save()
bookmaker.country_set.add(bookmaker)
bookmaker.save()
return HttpResponseRedirect(self.get_success_url())

Django chain multiple queries in view

I have three models:
Course
Assignment
Term
A course has a ManyToManyField which accesses Django's default User in a field called student, and a ForeignKey with term
An assignment has a ForeignKey with course
Here's the related models:
class Assignment(models.Model):
title = models.CharField(max_length=128, unique=True)
points = models.IntegerField(default=0, blank=True)
description = models.TextField(blank=True)
date_due = models.DateField(blank=True)
time_due = models.TimeField(blank=True)
course = models.ForeignKey(Course)
class Course(models.Model):
subject = models.CharField(max_length=3)
number = models.CharField(max_length=3)
section = models.CharField(max_length=3)
professor = models.ForeignKey("auth.User", limit_choices_to={'groups__name': "Faculty"}, related_name="faculty_profile")
term = models.ForeignKey(Term)
students = models.ManyToManyField("auth.User", limit_choices_to={'groups__name': "Student"}, related_name="student_profile")
When a user logs in to the page, I would like to show them something like this bootstrap collapse card where I can display each term and the corresponding classes with which the student is enrolled.
I am able to access all of the courses in which the student is enrolled, I'm just having difficulty with figuring out the query to select the terms. I've tried using 'select_related' with no luck although I may be using it incorrectly. So far I've got course_list = Course.objects.filter(students = request.user).select_related('term'). Is there a way to acquire all of the terms and their corresponding courses so that I can display them in the way I'd like? If not, should I be modeling my database in a different way?
https://docs.djangoproject.com/en/1.11/ref/models/querysets/#values
You could use values or values_list here to get the fields of the related model Term.
For example expanding on your current request:
To retrieve all the Terms' name and duration for the Courses in your queryset
Course.objects.filter(students = request.user).values('term__name', 'term__duration')
I am not sure what the fields are of your Term model, but you would replace name or duration with whichever you are trying to get at.
I think it helps you
terms = Terms.objects.filter(....) # terms
cources0 = terms[0].course_set.all() # courses for terms[0]
cources0 = terms[0].course_set.filter(students=request.user) # courses for terms[0] for user

django filter on max_length

Hi is there a way to filter on field attributes instead of field values in Django?
For example, for my GUI layout i want to know the ordering of fields ordered by max_length. My model:
class Person(models.Model):
name1 = models.CharField(max_length=220, default="")
name2 = models.CharField(max_length=90, default="")
name3 = models.CharField(max_length=30, default="")
name4 = models.CharField(max_length=130, default="")
name5 = models.CharField(max_length=10, default="")
I want to be able to find the length of the longest CharField in my model, in this case 220. How can i do that?
This is just an simplified example, but is similar to the functionality i need. To give insight in the real-world situation i am facing: I added a custom attribute to my model "gui_serial_number", I have partially static models with fields like:
a = CharField(gui_serial_number=10...)
b = CharField(gui_serial_number=20...)
....
n = CharField(gui_serial_number=50...)
I made an dynamic interface in which Fields can be dynamically added to the model (with type() and add_to_class() etc), and the user can give the place in the GUI where the field should be placed. I want to be able to automagically define the gui_serial_number to be "max+10" when no gui_serial_number is given.
Maybe it's not beautiful, but to find the length of the longest CharField of Person you can do this:
from operator import attrgetter
sorted([field for field in Person._meta.fields if isinstance(field, models.CharField)],
key=attrgetter('max_length'))[-1].max_length

Categories