How do I reference the other object in django models - django

first post here.In Django, I want to have many files be associated with a particular model, so I'm doing a seperate model called files and have model 'A' 'have many' files. But I want my files to be saved in director named by model 'A'. So For example I want something like this:
class Show(models.Model):
name = models.CharField()
showfolder = models.FilePathField()
class Episode(models.Model):
show = models.ForeignKey(Show)
name = models.CharField()
files = models.ManyToManyField(mp3)
class Mp3(models.Model):
file = FileField(upload_to=Episode.show.showfolder)
So hopefully that last line expresses what I WANT it to do(get the folder name from Show object associated with the episode). The question is how would I really write that?(besides jumping through hoops in the controller.)
Thanks.

In your current model because of Episode ManyToMany relation to Mp3 it is possible for one file to be associated with one or more episodes. That would mean that your file will have to simultaneously exist in several locations.
To have a hierarchical structure you need ForeignKey to Episode in Mp3 model:
class Mp3(Model):
episode = ForeignKey(Episode)
Now about your file name. According to django documentation, upload_to attribute can accept callable and will pass two arguments to it: instance and filename.
def get_file_name(instance, original_filename):
return os.path.join(MEDIA_ROOT, 'mp3', instance.episode.show.showfolder,
original_filename)
class Mp3(Model):
file = FileField(upload_to=get_file_name)

Related

django multi file upload fields

List item
registration start date
Year
Vin#
Make
Title Owner (Upload field) ==== (can be several files)
HUT # (Upload field) ==== (can be several files)
Ifta # (Upload field) ==== (can be several files)
I need that model
If file upload fields had to be for a single file, then it would be okay, but how Can I handle that model?
(Should I create ForeignKey models for every file_upload field in order to handle multi file uploads??)
I would write something like this:
files_titleowner = models.ManyToManyField(FileTitleOwner, related_name="mymodel_filetitleowner", blank=True)
...
and so on. I usually specify the related_name attribute for each many to many field.
FileTitleOwner could be like this:
class FileTitleOwner(models.Model):
file = models.FileField(upload_to=user_directory_path,
null=True, blank=True,
verbose_name="...")
...
Also, user_directory_path is a function which returns the pathname for the file to be stored on file system:
def user_directory_path(instance, filename):
...
return f"{<construct opportunely a directory name>}/{filename}"

Create django model with as many fields as an integer in other field

I have the following model in django
class params(models.Model):
name = models.CharField(max_length=30, default = 'no_name')
cs_n = models.IntegerField(default=16)
alt_n = models.IntegerField(default=2)
opt_out = models.BooleanField(default=1)
at_n = models.IntegerField(default=4)
I want to create a new model with as many fields as at_n. For example, if the user enter "4" in at_n, I want this to create automatically:
class params(models.Model):
at_1 = models.IntegerField(default=2)
at_2 = models.IntegerField(default=2)
at_3 = models.IntegerField(default=2)
at_4 = models.IntegerField(default=2)
Thanks
This probably isn't a good data model to follow as Django models are intended to closely mirror database tables. For example, you wouldn't want to dynamically update the DDL of a table in a database because doing so places you at risk of messing up data that already exists in said table.
Instead, I think it would be a better approach for you to re-evaluate your data model.
For example, if there was a main object you were trying to tie these attributes to, then make a model for that main object and then make a separate model for main object attributes/values.
From there, you could use view logic to actually validate that the appropriate number of attributes assigned to a particular main object.
I'm thinking something kind of like this:
class MainModel(models.Model):
....
{Your main model attributes}
at_n = models.IntegerField(default=4)
....
class MainModelAttributes(model.Model):
main_model = models.ForeignKey(MainModel)
attr_value = models.IntegerField()
Then in your views.py file, you could use logic to make sure that the number of attributes on the MainModelAttributes model match the number stored in MainModel.at_n.

Populating django model with objects from other model

I'm new to django, but working on an app for a volunteer sailing organization in my local area. Not sure how to ask this question since it's fairly general but I want the following to happen based on two models;
Yacht class (boat name, skipper, color, etc.)
Race_Event class (event date, time results for each boat)
Step 1: The user will need to create a Race_Event each week. I want the boats from the Yacht model to be loaded into the Race_Event.
Step 2: The user will enter race times for each boat.
Is there a way to pre-load objects from one model into another? With a ForeignKey the user has to add the boats each time. Any direction for me to research would be helpful.
Here is the simplified code so far;
class Yacht (models.Model):
yacht_classes = [('A', 'A'),('A1', 'A1'),]
yacht_type = [('J-29','J-29'),('J-24','J-24'),]
yacht_name = models.CharField(max_length=75)
yacht_type = models.CharField(max_length=25, choices=yacht_type,
default='J-29')
yacht_class = models.CharField(max_length=25, choices=yacht_classes)
skipper = models.ForeignKey(Skipper, on_delete=models.CASCADE)
def __str__(self):
return self.yacht_name
class Event (models.Model):
race_date = models.DateTimeField(default=timezone.now)
#yachts = #how to Include Yacht.objects.all() to the field?
class Results (models.Model):
pass
Thanks
Yes, u can use signals...
after objects is saved u can call post_save and add all yachts to race
more => https://docs.djangoproject.com/en/3.1/ref/signals/#post-save
but i dont think this is good way...
(not every time all the data must be present or must be saved => this save rows in database)
i recomment you to use m2M between race and ship with throught table where time is saved in table between.
then its on you how you present this problem to end-user.
with this solution you save only data which are needed.
this can be done with
https://docs.djangoproject.com/en/3.1/topics/db/models/#extra-fields-on-many-to-many-relationships

Figuring out how to design my model and using "through"

I'm trying to figure out how to design my model. I've been going over the documentation, and it ultimately seems like I should be using the "through" attribute, but I just can't figure out how to get it to work how I want.
If someone could take a look and point out what I'm missing, that would be really helpful. I have pasted my model below.
This is what I am trying to do:
1) Have a list of server types
2) Each server type will need to have different parts available to that specific server type
3) The asset has a FK to the servermodel, which has a M2M to the parts specific to that server type.
My question is, how can each "Asset" store meta data for each "Part" specific to that "Asset"? For example, each "Asset" should have it's own last_used data for the part that's assigned to it.
Thanks! :)
class Part(models.Model):
part_description = models.CharField(max_length=30,unique=1)
last_used = models.CharField(max_length=30)
def __unicode__(self):
return self.part_description
class ServerModel(models.Model):
server_model = models.CharField(max_length=30,unique=1)
parts = models.ManyToManyField(Part)
def __unicode__(self):
return self.server_model
class Asset(models.Model):
server_model = models.ForeignKey(ServerModel)
serial_number = models.CharField(max_length=10,unique=1)
def __unicode__(self):
return self.server_model.server_model
EDIT:
Thank you for the help!
I may have not explained myself clearly, though. It's probably my confusing model names.
Example:
ServerModel stores the type of server being used, say "Dell Server 2000".
The "Dell Server 2000" should be assigned specific parts:
"RAM"
"HARD DISK"
"CDROM"
Then, I should be able to create 10x Assets with a FK to the ServerModel. Now, each of these assets should be able to mark when the "RAM" part was last used for this specific asset.
I'm not sure I exactly understand what you want to do, but basically you can solve that with a "through" model, as you expected:
import datetime
class Part(models.Model):
name = models.CharField(max_length=30,unique=1)
class ServerModel(models.Model):
server_model = models.CharField(max_length=30,unique=1)
parts = models.ManyToManyField(Part,through='Asset')
class Asset(models.Model):
server_model = models.ForeignKey(ServerModel)
part = models.ForeignKey(Part)
serial_number = models.CharField(max_length=10,unique=1)
used = models.DateTimeField(default=datetime.datetime.now())
First thing to notice is the relation of the parts to the servermodel using the "through"-model: that way for each Part instance assigned to the "parts"-property of a ServerModel instance a new Asset instance is created (Phew - hope that doesn't sound too complicated). At the time of creation the "used"-property of the Asset instance is set to the current date and time (thats what default=datetime.datetime.now() does).
If you do that, you can then just query the database for the last asset containing your part. That queryset can then be sorted by the "used" property of the Asset model, which is the date when the Asset instance has been created.
ServerModel.objects.filter(parts__name='ThePartYouAreLookingFor').order_by('asset__used')
I'm not absolutely sure if the queryset is correct, so if someone finds huge nonsense in it, feel free to edit ;)
edit:
The models above do not exactly that. But you do not even need a through model for what you want:
class ServerModel(models.Model):
server_model = models.CharField(max_length=30,unique=1)
parts = models.ManyToManyField(Part)
class Asset(models.Model):
server_model = models.ForeignKey(ServerModel)
parts = models.ForeignKey(Part)
serial_number = models.CharField(max_length=10,unique=1)
used = models.DateTimeField(default=datetime.datetime.now())
Basically you can just add assets and then query all assets that have a RAM in parts.
Asset.objects.filter(parts__contains='RAM').order_by('used')
Get the date of the first (or last) result of that queryset and you have the date of the last usage of your 'RAM'-part.

Django admin: Restrict many-to-many relationship items to newly created ones

My problem is that I don't really know how to put my design in terms of a relational db.
I have a class 'Feat', which should contain several other classes, namely lists of 'Stat's, 'Skill's and 'Attribute's. The exact number of those depends on the instance of 'Feat', so I can't just define a static number of fields.
In normal Python, I'd simply use lists:
class Feat():
name
desc
att_effects = []
skill_effects = []
stat_effects = []
I tried to replicate this in Django using the Many-to-Many relationship, but that didn't quite work out.
class Attribute_Name(models.Model):
name = models.CharField(max_length=100)
desc = models.TextField()
def __unicode__(self):
return str(self.name)
...
class Attribute(models.Model):
name = models.ForeignKey(Attribute_Name)
value = models.IntegerField()
def __unicode__(self):
return "%s: %s" % (self.name, self.value)
...
class Feat(models.Model):
name = models.CharField(max_length=100)
desc = models.TextField()
att_effects = models.ManyToManyField(Attribute)
skill_effects = models.ManyToManyField(Skill)
stat_effects = models.ManyToManyField(Stat)
With these models, I could create new 'Attribute's when creating a new 'Feat' in the admin interface. However, I would always see all existing 'Attribute's, not just those pertaining to my new 'Feat'. Is there a way to restrict the view to only those created along with the new 'Feat'? Something like a back-link to the 'Feat' which created the 'Attribute'?
Basically, when I create or edit a 'Feat', I should only be able to use 'Attribute's created from the page of this instance or add a new 'Attribute' instance. I don't want 'Attribute's belonging to another 'Feat' (or another unrelated class) to show up.
Note that I don't want to add a field to the 'Attribute' class, since it should also be used along with other classes (eg 'Character')
I'd also like to do this within the admin interface, since it saves me quite a bit of work.
On a related note: Is there a way to leave a Many-to-Many field empty? Or should I just create a magic 'empty' value and set it as the default?
"there a way to restrict the view to only those created along with the new 'Feat'? Something like a back-link to the 'Feat' which created the 'Attribute'?"
Yes: use the queryset feature of ModelAdmin as described in this question