Remove field from a subclass of base abstract class Django
I am creating an application which needs a commenting system. I decided to use the comment app of Django, but needed to alter it a bit. First I do not want the user's email id to be mandatory and next I need an option to attach a file with the comment.
Thus I decided to subclass from BaseCommentAbstractModel. Now I need to override the user_email to be
user_email= models.EmailField(max_length=100, blank=True)
and add another field
file = models.FileField(upload_to='data/files')
My code should look like this:
from django.db import models
from django.contr开发者_开发百科ib.comments.models import BaseCommentAbstractModel
class CommentWithFile(BaseCommentAbstractModel):
'''This is a hack of the Comment model to remove email and add a filefield'''
user_email = models.EmailField(max_length=100, blank=True)
file = models.FileField(upload_to='data/files')
but this does not work. The user_email is still mandatory. Any ideas?
Are you sure that the issue is to do with the model? BaseCommentAbstractModel
doesn't even define user_email
, that's only in the main Comment
model - and it's defined as blank=True
in any event.
I think it's more likely that you need to provide a custom form. The main CommentDetailsForm
is not a modelform - it manually defines its fields, including a required email
field. Sounds like you need to override that too.
Since Django 1.10 you have the ability to override abstract fields (i.e. fields of abstract base models).
Field name “hiding” is not permitted
[...]
This restriction doesn’t apply to model fields inherited from an abstract model. Such fields may be overridden with another field or value, or be removed by setting
field_name = None
.
So the code you provided for the way you want your model to be is valid since Django 1.10.
Just create custom form with a help of django generic views.
Models.py should look something like:
from django.utils.translation import ugettext_lazy as _
from django.db import models
from django import forms
class Comments(models.Model):
name = models.CharField(_('Name'), max_length=30)
email = models.EmailField(_('Email'), blank=True, null=True)
comment = models.TextField(_('Comment'))
date = models.DateTimeField(_('Date'), auto_now_add=True)
file = models.FileField(_('File'), upload_to='data/files')
publish = models.BooleanField(_('Publish'))
def __unicode__(self):
return self.name
Short answer: no.
http://docs.djangoproject.com/en/dev/topics/db/models/#field-name-hiding-is-not-permitted
Long answer: it depends.
You can for instance overwrite the init and save() methods to put in the field some default value (e.g. anonymous@example.com, an address that is fake by definition) and you'll then manage that case in code.
精彩评论