I'm just starting on my first ASP.NET MVC project (it's actually extending an existing MVC project that uses 4.0 and Linq2SQL). What I'm looking for is a way to create an instance of a model every time a different model is created (i.e., saved to the database). I see an OnCreated() method in the generated code, but that's in a partial class, so I can't replace it/ override it.
Is there a way to tie things together like this? I feel like I've been working in Django so long (where I would use a signal) that I don't know the right term to search for.
EDIT: What I want to do -- every time an instance of Model A is saved to the database for the first time (and only the first time), I want to create an instance of Model B and save that to the database.
And it looks like OnCreated() doesn't have anything to do with that.
You can always override the save method.
class A(models.Model)
def save(self,**kwargs):
super(A,self).save(**kwargs)
if self.pk: #Primary Key is assigned only after the save.
B.objects.create()
return self
Related
An Setting belongs to an Office. Each time a Setting is updated, I make a new entry in the database, passing the old Setting to active=False and the new Setting to active=true. So each office has only one active setting at a time (i'm doing this because I wan't to keep track of old settings).
Now what I need is a way to access this setting via the Office object.
At the moment I am accessing it with the backwards relation office.setting_set.
I'm using Django-Rest-Framework so I need a field that is serializable.
In my serializer, I call: office.setting_set. In regular django I could probably do office.setting_set.filter(active=True) but I can't do so in a serializer...
The ideal would be a custom model field that I would call something like:
office.active_setting
Any idea how I can achieve this?
You can use model methods for this. The method would likely be something similar to the following:
def active_setting(self):
return self.setting_set.get(active=True)
I have two models. One called MainModel and other called HistoricMainModel. I would like to INSERT automatically a row in the HistoricMainModel every time I data is inserted to MainModel. What is best/correct way of doing this in Django?
Best Regards,
If you already have some custom save().-magic going on I would recommend using a post_save() signal or a pre_save() which ever would work best for you.
in your models.py
#receiver(pre_save, sender=MainModel)
def save_a_historicmodel(sender, **kwargs):
#do your save historicmodel logic here
or
def save_a_historicmodel(sender, instance, created, **kwargs):
print "Post save was triggered! Instance:", instance
signals.post_save.connect(save_a_historicmodel, sender=MainModel)
This works so that every time your MainModel is saved this signal is triggered.
Docs here
Rewrite save method in MainModel model to create and insert the HistoricMainModel object before calling the "real" save method.
You could implement this yourself but the best way would be to use an application that does this - like reversion - a django app that implements model history/roll back automatically.
In addition to whatever you will implement, reversion will provide you with:
Integration with the admin backend.
A API to add meta-data to your versions and to revert back to previous versions of your model.
It is a lot more flexible and is widely used and implemented.
I'm wondering what the appropriate things to put in my model's clean() method are.
Does it make sense to put all the verification of and manipulation to a model's properties to ensure it is valid (ie. business logic)? There is a lot of that in my case and I'm wondering if it makes sense to execute it all every time a model is saved.
For example i'm doing things like :
- if a video is marked as private, remove all its references in playlsts
- ensure that the video's title is unique with relation to the users other videos
- etc.
some of the things i'm doing only really need to be done on creation of a new video - so checking/ setting them every time the model is saved also seems excessive.
Is this the correct use of the clean() method?
Clearing relationships is probably best handled by a signal. To validate your signals are working properly, you can write a unit test.
Validating that the title is unique is something that definitely belongs in a form/model validator. To me, that seems like a better separation of concerns.
I want to add a layout model to my website (a general settings file), and I want it to be available in the admin interface for configuration.
class Layout(...Model):
primary_header
logo_image
...
This structure shouldn't saved be in a table.
I am wondering if there is a built-in feature that can help me do this.
Thanks
My use case is a configurable layout of the website. Wordpress style. I would like to store that data in a concrete class, without having to implement the file /xml serialization myself.
What about an abstract model? It does not save in the database and is meant to be subclassed, but you are allowed to create instances of it and use its attributes. I assume you want some kind of temporary data structure to pass around that meets the requirements of a model instance.
class Layout(models.Model):
class Meta:
abstract = True
If you for some reason need actual concrete models, and are fine with it creating tables for them, you could technically also re-implement the save() method and make it no-op.
I don't really understand where and how you will be using this, but this is indeed a model that doesn't save.
Personally, I have actually used models that aren't intended to be saved, in a project that uses mongodb and the nonrel django fork. I create models that are purely meant to be embedded into other models as nested sub-documents and I never want them to be committed to a separate collection.
Update
Here is another suggestion that might make things a whole lot easier for your goal. Why not just use a normal django model, save it to the database like normal, and create a simple import/export function to save it out to XML or read into an instance from XML. That way you get 100% normal admin functionality, you can still query the database for the values, and the XML part is just a simple add-on. You can also use this to version up preferences and mark a certain one as active.
I want to make the following modification to the Django framework.
I want it to create a "deleted" field for each model I create.
I want it to be checked as deleted when I delete it from the admin page instead of being physically deleted.
I do not want these records checked as deleted to be listed.
I'm new to Django, I'm seeing if I can do what I want to do with it easily. I need this change because it's the way we currently work.
So far these are the changes I have made, I would like to understand how the whole Django framewok works inside but I'm so far from that, is there any documentation online which explains clearly how the inside framework parts/files/modules/classes work together, the specific role of each one, etc
In the base.py file, in the modelbase class, below this code,
for obj_name, obj in attrs.items():
new_class.add_to_class(obj_name, obj)
I added,
from django.db import models
new_class.add_to_class('deleted', models.BooleanField())
When it creates a model it adds the "deleted" field to it.
In the base.py file, in the save method, I changed what it was there for
self.deleted = True
self.save()
So, now it check as deleted a record instead of physically delete it.
Now what I want is those records not to be listed.
I don't understand why you're modifying the framework code instead of putting your deleted field in a model base class that all of your models extend from.
Nevertheless, a nice way to filter those records out would be to add a custom manager to the model (or your base model class, if you choose to create one). To this manager, override the get_query_set method as described here. In your overridden method, add a exclude(deleted=True) filter.
Take a look at the Django-logicaldelete app, You just inherit your models from their provided Model class and you get Logical delete for all of them.
It comes with an adminModel as well so you can manage logically deleted models there too.
Override the delete() method in your model class, set the deleted attribute there
Create a custom manager which will filter by deleted attribute and set it as the default one (objects = MyDeletedManager)