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.
Related
I am starting a web application in pure Django. However, in the future, there might be a requirement for REST api. If it happens, the most obvious choice will be Django REST framework.
Both the "old-fashioned" and REST parts share the models, however, the views are slightly different (permissions definitions, for example) and forms are replaced with serializers. Doing it the most obvious way would mean to duplicate the application logic several times, and thus a failure to follow DRY principle, and so the code becomes unmaintainable.
I got an idea to write all the logic into models (since they are shared), but in such case, there will be no use of permission mixins, generic views and the code would not be among the nicest ones.
Now I ran out of ideas. What is the best practice here?
I'd try to keep things simple as you're not sure about the future requirements for the API, and guessing can introduce extra complexity that may not even be needed when requirements will be clear.
Both Django forms and Rest Framework serializers already offer you a declarative approach that abstracts away the boilerplate code needed for basic stuff, which normally accounts for most of your code anyway.
For example, one of your Django form could look like this:
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['title', 'content']
And in the future the DRS serializer would be:
class ArticleSerializer(ModelSerializer):
class Meta:
model = Article
fields = ['title', 'content']
As you can see, if you try and stick to ModelForm and ModelSerializer, there won't be much duplication anyway. You can also simply store the fields list in a variable and just reuse that.
For more custom things, you can start by sharing logic into simple functions, for example:
def save_article_with_author(article_data, author_data):
# custom data manipulation before saving, consider that article_data will be a dictionary either if it comes from deserialized JSON (api) or POST data
# send email, whatever
This function can be shared between your form and serializer.
For everything related to data fetching, I'd try to use Model Managers as much as possible, defining custom querysets that can be resued e.g. for options by forms and serializers.
I tend to avoid writing any logic that doesn't directly read or write data into the model classes. I think that couples too much the business logic with the data layer. As an example, I never want to write any auth/permission checks into a save() method of a model, because that couples different layers too tightly.
As a rule of thumb, imagine this scenario: you add say permissions checks or the logic to send an email when a user is created overriding the save() method of your Article model.
Then, later on you're asked to write a simple manage command that batch-import users from a spreadsheet. At this point, what you did in your save() method really gets in the way, as you can freely access your data through your model without having to bother with permissions, emails and all of that.
Regarding the view layer and assuming you need to implement some shared auth/permission checks and you don't want to have separate views, you can use this approach:
https://www.django-rest-framework.org/topics/html-and-forms/
Blockquote
REST framework is suitable for returning both API style responses, and regular HTML pages. Additionally, serializers can be used as HTML forms and rendered in templates.
Here's some guidelines on how you could dynamically switch from HTML to JSON based to the request content type:
https://www.django-rest-framework.org/api-guide/renderers/#advanced-renderer-usage
This seems like a good option in your situation, I'd just write down a quick proof-of-concept before you go all in to see if you are not too limited for what you need to do.
I'm developing a website in Django where many of the sites' models' instances are presented to the user in a standardized format on many different pages. I'd like to avoid redundancy in the template coding by creating standard model instance template code then just inserting it each page where a model instance needs to be displayed.
What is the best practice for creating standardized instance display code, then adding it into many different pages?
There are several ways of accomplishing this...
One is to use an include tag and pass your object to the template. Another, similar approach is to create a template tag to render the object, which is useful if you need to do some extra processing in Python before doing the rendering.
Yet another way is to add an instance method to your model to render itself to HTML (or some other format), much the same way a form instance has .as_ul or .as_p that you can call in your template where needed.
Neither way is right or wrong, it just depends on what you're most comfortable with stylistically and what's most efficient for your needs.
When I create a class/model specifically for the purposes of being embedded into another class/model, a collection is still written for the former in my mongodb database. The aforementioned does not cause any trouble other than the inconvenience of being there, but I'm still wondering if there is any way for a collection not to be written?
I have a nonrel django project as well. Its just a thing django does (and that the nonrel fork has not specifically addressed), that when you define a model that is not abstract or proxy, it is going to generate a collection (table) during a syncdb. Whether you save anything to that collection is further dependent on your code obviously.
If there is some trick to having a concrete model not create a collection in nonrel django, then I am missing something as well.
It's possible if you use abstract=True for that model.
However, you can't use lazy lookup (aka EmbeddedModelField('SomeModelThatsNotYetDefined') yet (https://github.com/django-nonrel/djangotoolbox/issues/15).
I need to provide my users a list of choices from a model which is stored in a separate legacy database. Foreign keys aren't supported in django multi-db setups. The ideal choice would be to use a foreign key, but since thats not possible I need to some up with something else.
So instead I created an IntegerField on the other database and tried using choices to get a list of available options.
class OtherDBTable(models.Model):
client = models.IntegerField(max_length=20, choices=Client.objects.values_list('id','name'))
the problem I'm having is that the choices seem to get populated once but never refreshed. How do I ensure that whenever the client list changes that those newest options area available to pick.
What I was really looking for was a way that I could simulate the behavior of a Foreign key field, at least as far as matching up ID's go.
There wasn't a clear way to do this, since it doesn't seem like you can actually specify an additional field when you instantiate a model (you can with forms, easily)
In any case to deal with the problem, since the database is MySQL based, I ended up creating views from the tables I needed in the other database.
To build on #Yuji's answer - if you do self.fields['field'].choices = whatever in the model's __init__, whatever can be any iterable.
This means you can inherit from iterable, and have that object interface to your legacy database, or you can use a generator function (in case you are unfamiliar, look up the yield keyword).
Citing a Django's manual:
Finally, note that choices can be any iterable object -- not necessarily a list or tuple. This lets you construct choices dynamically. But if you find yourself hacking choices to be dynamic, you're probably better off using a proper database table with a ForeignKey. choices is meant for static data that doesn't change much, if ever.
Why dont you want just export data from the legacy database and to import it into the new one? This could be done periodically, if the legacy database still in use.
I'm developing web page with many type of users, each with different profiles properties. I would like to use built in auth system but:
a) I want to use django-registration.
b) I can point User.get_profile to only one profile model.
How to accomplish that in nice fashion?
I haven't used django-registration so I don't know what it entails. For the second part of your question one way would be to
Associate an UserProfile with every User
Add different kinds of ProfileProperty classes and link to them from UseProfile using a generic relationship.
I know, it is a bit of a stretch.
I'm not an expert nor in python, django or database but I encountered a somewhat similar issue few weeks ago and on #django someone advised me to use Generic relation to achieve that.
I created a UserProfile model that is liked (through a OneToOnefield) to the "true" profile, and using contrib.content-type and generic relation I'm able to use several distinct porfile types.
Note that should work for you if you don't fear to hit you database one more time on each get_profile().
An alternative would be to create a big table that contain all the field for all the profile type and using some kind of hook (or reimplementing a custom save()) to check the retired fields according the profile type. But it look complicated to me, especially if you want to have a lot of different profile type.
Another alternative could be to create a TextField derivated custom field and use it as a storage for a dictionary that you pickle to it on save and unpickle from it on load. With some hacking you could certainly map some of the model attribute to the dictionary key. That would allow a lot of flexibility.
Free hint for ya : I also use fixtures to test my application and forgot to check if the raw parameter of the post_save signal was True to prevent executing the UserProfile creation when using manage.py loaddata. As I had coded the creation of the "true" profile in my post_save callback the exception what kind of weird until I find out what was happening.
Usefull ressource :
defining a profile
generic relation