I am attempting to create a model class that all models will inherit from when they are created (in Django). I want any model class, with any attributes to be able to inherit from this class and read from the appropriate database table.
I know I am going need to use **kwargs and .setattr() at some point but am unclear as to where I even start. I am also going to try to recreate .all(), .filter() and .get() with in that class that all other methods that inherit this class can access.
This is what I have so far:
import sqlite3
class Model:
def __init__(self):
pass
#classmethod
def all(self, **kwargs):
pass
#classmethod
def get(self):
pass
#classmethod
def filter(self):
pass
###don't touch the code for these
class Users(Model):
pass
class Stocks(Model):
pass
How can I go about the initialization of this class?
It looks like you're trying to insert an abstract base class for your models.
Basically, what you've got there is correct, except you're missing
from django.db.models import Model
class MyModelBase(Model):
class Meta:
abstract = True
# ... The fields and methods I want all my models to inherit.
Then rather than making your models inherit from django.db.models.Model, they should inherit from MyModelBase.
Related
I am using django-parler for language translation in an abstract class model but I get this error: raise TypeError("Can't create TranslatedFieldsModel for abstract class {0}".format(shared_model.__name__)) TypeError: Can't create TranslatedFieldsModel for abstract class MyClass
I want to know why I can't create an instance of this TranslatedFieldsModel in an abstract class. Are there some instance or some type of classes/objects that cannot be instantiated in an abstract class? I really don't know much about abstract classes, please explain to me why this TranslatedFieldsModel cannot be created and how to go about it
Here is a code example:
from django.db import models
from parler.models import TranslatableModel, TranslatedFields
class MyClass(TranslatableModel):
translations = TranslatedFields(
title = models.CharField(max_length=500)
)
class Meta:
abstract = True
when I run my app I get the error above:
My question now is why is this so that I cannot create this instance in my abstract class? How can I make this work?
I have an abstract mixin class that adds a Django model field to any concrete class that inherits from it.
At class initialisation - when makemigrations is run - I'd like the inheriting class to define whether an inherited field is required or optional via the blank= True or False property.
I've tried various Meta and __new__ approaches, but can't figure out how the abstract mixin class can get the information from the inheriting class.
Here's a naive attempt:
from django.db import models
class DescriptionMixin(models.Model):
class Meta:
abstract = True
description = models.TetxField(
# how to get value here?
blank=inheriting_class.description_required
)
class OptionalDescription(DescriptionMixin, SomeOtherClass):
class Meta:
verbose_name = 'Optional description'
description_required = False
class RequiredDescription(DescriptionMixin, SomeOtherClass):
class Meta:
verbose_name = 'Required description'
description_required = True
Thanks in advance for any help offered.
You can't do this at the database level. makemigrations doesn't actually initialise your models to create the migration files.
But since you're trying to enforce this on a TextField, which cannot be enforced at the database level anyway (blank is only used when validating a model through the full_clean() method), you could just override the clean() method on the DescriptionMixin, checking the value of self.blank and raising a ValidationError appropriately.
Solved using this (it's actually Wagtail on top of Django):
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs)
self._meta.get_field('description').blank = not getattr(self, 'description_required', False)
I've got the following class
class UserProfile(models.Model):
# ...
#property
def get_fields(self):
return [(field.name, field.value_to_string(self)) for field in UserProfile._meta.fields]
I want to use that property on all my classes. So I want to make a mixin.
class HelperMixin(object):
#property
def get_fields(self):
return [(field.name, field.value_to_string(self)) for field in UserProfile._meta.fields]
Trouble is, the property has class specific code in it. How do I generalize the code to work in other classes?
And what is the difference when I use it like this:
class UserProfile(models.Model, HelperMixin)
vs. like this
class UserProfile(HelperMixin, models.Model)
Use self._meta.fields, class members are available on instances as well:
class HelperMixin(object):
#property
def get_fields(self):
return [(field.name, field.value_to_string(self)) for field in self._meta.fields]
The differense between class UserProfile(models.Model, HelperMixin) and class UserProfile(HelperMixin, models.Model) lies in the MRO (method resolution order). It would seem natural to have the mixin before the base class, but as long as the base and the mixin does not have members with the same name it makes no difference.
In my Django app, I am using a model (let's call it Mymodel), and a form :
class Mymodel(models.Model):
firstField(...)
secondField(...)
class MymodelAddform(ModelForm):
def clean_firstField(self):
#stuff
def clean_secondField(self):
#stuff again
def clean(self):
#performs stuff with all the fields
class Meta:
model = Mymodel
Now I want to add another form, MymodelEditform, based on Mymodel again, using only secondField, and only secondField validation
Two options I've considered (both do not work as I wrote them) :
class MymodelEditform(ModelForm):
class Meta:
model = Mymodel
fields = ['secondField']
Here the problem is that clean_secondField is not called unless I re-define it, and I would like to avoid having clean_secondField call another method defined elsewhere (though, if it is the only option, so be it)
class MymodelEditform(MymodelAddform):
class Meta:
model = Mymodel
fields = ['secondField']
Here the problem is that the clean() validation is called, and since I'm only using a subset of the fields, it fails.
The question is pretty obvious : how can I make it work as intended?
I haven't done this, but you can try this.
Create a simple class with clean methods.
As below
class MymodelformCleaner(ModelForm):
def clean_firstField(self):
#stuff
def clean_secondField(self):
#stuff again
Inherit your model forms from this class
Your model forms will just define the fields, while clean methods come from another class
class MymodelAddform(ModelForm, MymodelformCleaner):
class Meta:
model = Mymodel
class MymodelEditform(ModelForm, MymodelformCleaner):
class Meta:
model = Mymodel
fields = ['secondField']
An obvious solution would be to define clean_secondField in MymodelEditform and make MyModelAddForm inherit from MymodelEditForm, but it might not work as expected. Another solution would be to make both forms inherit from a common base form defining clean_secondField.
Or you could just explicitely exclude the field in the form's Meta (cf https://code.djangoproject.com/ticket/12901)
just a very simple thing, is there a way to access outer class from the inner class definition, like this:
class Model:
class Options:
model = Model <-- error!
I nest Options inside Model because semantically these Options exist only in the scope of model, so it seems appropriate.
Thanks,
Alex
I am not sure this is exactly what you wanted but try:
class Model:
class Option:
#property
def model(self): return Model
Well, you can at least instantiate the outer class in a method of the inner class:
class Model:
class Options:
def __init__(self):
model = Model()
Try:
class Model:
pass
class Options:
model = Model
Another solution is to do the assignment after the class definition.
class Model:
class Options:
pass
Model.Options.model = Model