English 中文(简体)
Django models generic modelling
原标题:

Say, there is a Page that has many blocks associated with it. And each block needs custom rendering, saving and data.

Simplest it is, from the code point of view, to define different classes (hence, models) for each of these models. Simplified as follows:

class Page(models.Model):
    name = models.CharField(max_length=64)

class Block(models.Model):
    page = models.ForeignKey(Page)

    class Meta():
        abstract = True

class BlockType1(Block):

    other_data = models.CharField(max_length=32)

    def render(self):
        """Some "stuff" here """
        pass

class BlockType2(Block):

    other_data2 = models.CharField(max_length=32)

    def render(self):
        """Some "other stuff" here """
        pass

But then,

  • Even with this code, I can t do a query like page.block_set.all() to obtain all the different blocks, irrespective of the block type.
  • The reason for the above is that, each model defines a different table; Working around to accomplish it using a linking model and generic foreign keys, can solve the problem, but it still leaves multiple database tables queries per page.

What would be the right way to model it? Can the generic foreign keys (or something else) be used in some way, to store the data preferably in the same database table, yet achieve inheritance paradigms.

Update:

My point was, How can I still get the OOP paradigms to work. Using a same method with so many ifs is not what I wanted to do.

The best solution, seems to me, is to create separate standard python class (Preferably in a different blocks.py), that defines a save which saves the data and its "type" by instantiating the same model. Then create a template tag and a filter that calls the render, save, and other methods based on the model s type.

最佳回答

Don t model the page in the database. Pages are a presentation thing.

First -- and foremost -- get the data right.

"And each block needs custom rendering, saving and data." Break this down: you have unique data. Ignore the "block" and "rendering" from a model perspective. Just define the data without regard to presentation.

Seriously. Just define the data in the model without any consideration of presentation or rending or anything else. Get the data model right.

If you confuse the model and the presentation, you ll never get anything to work well. And if you do get it to work, you ll never be able to extend or reuse it.

Second -- only after the data model is right -- you can turn to presentation.

Your "blocks" may be done simply with HTML <div> tags and a style sheet. Try that first. After all, the model works and is very simple. This is just HTML and CSS, separate from the model.

Your "blocks" may require custom template tags to create more complex, conditional HTML. Try that second.

Your "blocks" may -- in an extreme case -- be so complex that you have to write a specialized view function to transform several objects into HTML. This is very, very rare. You should not do this until you are sure that you can t do this with template tags.


Edit.

"query different external data sources"

"separate simple classes (not Models) that have a save method, that write to the same database table."

You have three completely different, unrelated, separate things.

  • Model. The persistent model. With the save() method. These do very, very little. They have attributes and a few methods. No "query different external data sources". No "rendering in HTML".

  • External Data Sources. These are ordinary Python classes that acquire data. These objects (1) get external data and (2) create Model objects. And nothing else. No "persistence". No "rendering in HTML".

  • Presentation. These are ordinary Django templates that present the Model objects. No external query. No persistence.

问题回答

I just finished a prototype of system that has this problem in spades: a base Product class and about 200 detail classes that vary wildly. There are many situations where we are doing general queries against Product, but then want to to deal with the subclass-specific details during rendering. E.g. get all Products from Vendor X, but display with slightly different templates for each group from a specific subclass.

I added hidden fields for a GenericForeignKey to the base class and it auto-fills the content_type & object_id of the child class at save() time. When we have a generic Product object we can say obj = prod.detail and then work directly with the subclass object. Took about 20 lines of code and it works great.

The one gotcha we ran into during testing was that manage.py dumpdata followed by manage.py loaddata kept throwing Integrity Errors. Turns out this is a well-known problem and a fix is expected in the 1.2 release. We work around it by using mysql commands to dump/reload the test dataset.





相关问题
what is wrong with this mysql code

$db_user="root"; $db_host="localhost"; $db_password="root"; $db_name = "fayer"; $conn = mysqli_connect($db_host,$db_user,$db_password,$db_name) or die ("couldn t connect to server"); // perform query ...

Users asking for denormalized database

I am in the early stages of developing a database-driven system and the largest part of the system revolves around an inheritance type of relationship. There is a parent entity with about 10 columns ...

Easiest way to deal with sample data in Java web apps?

I m writing a Java web app in my free time to learn more about development. I m using the Stripes framework and eventually intend to use hibernate and MySQL For the moment, whilst creating the pages ...

join across databases with nhibernate

I am trying to join two tables that reside in two different databases. Every time, I try to join I get the following error: An association from the table xxx refers to an unmapped class. If the ...

How can I know if such value exists in database? (ADO.NET)

For example, I have a table, and there is a column named Tags . I want to know if value programming exists in this column. How can I do this in ADO.NET? I did this: OleDbCommand cmd = new ...

Convert date to string upon saving a doctrine record

I m trying to migrate one of my PHP projects to Doctrine. I ve never used it before so there are a few things I don t understand. In my current code, I have a class similar to this: class ...

热门标签