2

I have a User model with some fields. Some of them will require feedback, are they correctly filled (if not, specific message will be displayed on user profile).

The problem is, how to represent 'invalid' fields in database. My idea is to create another model (call it ExtUser) with OneToOneField to User. And ExtUser should have same fields' names as User, but their types will be all boolean, determining whether field is filled in correctly. For example, if User has a field called email:

email = models.CharField(max_length=100)

ExtUser would have following field:

email = models.BooleanField(default=False)

Here's a problem with this approach. How am I supposed to create fields in ExtUser? Of course I can create them manually, but that would be breaking of DRY principle, and I'm not going to do that. The question is, can I add fields to model dynamically, and have them in database (so I assume it would require to be called before migrate)?

I have django 1.8 and I don't want to use any external modules/libraries.

If someone has an another idea of how to represent that data in database, please add comment, not a reply - as this question is about creating fields dynamically.

mkzwm
  • 495
  • 4
  • 18

1 Answers1

1

You will need to do this manually.

Python does not disallow this behavior; you can take a look at this SO response on dynamically created classes, but Django will not be able to interpret the output. In particular, Django relies on the models to create the SQL tables for the application, and there is essentially no way for this to occur if you model is not statically defined.

In this case, I don't think you have to worry much about DRY; if you need a separate model with fields which happen to be related to, but different from, another model, I think it's probably ok.

Finally, I'm unsure what your goal is, but you could probably define some functions which can determine how "correct" the fields of the user are. This is how I would recommend solving this problem (if it applies).

Community
  • 1
  • 1
GJStein
  • 648
  • 5
  • 13
  • Before I asked, I've found this: http://blog.jupo.org/2011/11/10/django-model-field-injection/ It works, but only if I'm migrating one app (maybe this statement is wrong, I hadn't enough time do debug, but migrating on old database adds new fields correctly). When all migrations are applied (e.g. new database), I get `django.db.utils.OperationalError: duplicate column name: new_field` – mkzwm Jul 16 '15 at 20:49
  • 1
    Quite interesting indeed! I'll take a look and see what I can do. – GJStein Jul 16 '15 at 20:50
  • Also, these functions checking corectness do not exist, unfortunately. I'll need to compare text values to image. Too complicated and rare enough to not get automated. – mkzwm Jul 16 '15 at 20:52
  • I see your point on the checking functions (it was just a thought). From the article you linked: "This means that migration tools likes South are unable to detect the new fields, and workarounds such as creating manual migrations are required". This makes me think that this approach (especially for only a single class) is more work than it's worth for you. According to this quote, you'll still have to something manually, and making migrations yourself is quite a pain. I'd still recommend simply adding the fields to ExtUser. – GJStein Jul 16 '15 at 20:55
  • Well, I'd rather add a CharField which will contain incorrect fields' names and verbose names. I don't like it, but it comes to me as better solution than adding fields manually :) Also, about that point of manual migrations, here comes the specificity of project I'm writing. Models won't be changed during production, and production phase is only about 2 weeks long. So it wouldn't be a problem to just delete old database. Anyway, I hope someone someday will come with explanation why the duplicate column error is raised. – mkzwm Jul 16 '15 at 21:07
  • The duplicate column issue is indeed strange. Post it as a separate question if you can repeat it (along with your procedure). – GJStein Jul 16 '15 at 21:13