How to make auto-genertion(auto-fill and increment) in django admin - django

I want to make code field should be auto filled and auto increment in django admin.
models.py
class GeneralDocumentType(models.Model):
code = models.CharField(max_length=10, null=False, unique=True)
name = models.CharField(max_length=100, null=False, unique=True)
description = models.TextField(blank=True, null=True)
def __str__(self):
return self.name
I want to show my code field default=DOC001, and it will show increment by 1 before adding data by user.How can I achieve this?..

Django ModelAdmin has support for get_changeform_initial_data. In your admin you can override this method to get value based on the latest id info. For example:
class YourModelAdmin(admin.ModelAdmin):
...
def get_changeform_initial_data(self, request):
# getting the latest id
try:
latest_document_type = GeneralDocumentType.object.latest('id')
latest_id = latest_document_type.id + 1
except GeneralDocumentType.DoesNotExist:
# incase there no object yet
latest_id = 0
return {'code': f'DOC{latest_id}'}
Note: this only work for adding new object, ModelAdmin. Doesn't work for InlineModelAdmin

Related

Django Advice - model_to_dict - User returning ID instead of username

I'm calling the model_to_dict function and it is working,
but i want to be able to modify the results before returning.
The Author area is currently returning an id number and I want it to return the Username instead.
Does anybody know how to make that happen?
.model
class Comment(models.Model):
poopfact = models.ForeignKey(PoopFact, related_name="comments", on_delete=models.CASCADE)
author = models.ForeignKey(User, on_delete=models.CASCADE)
comment = models.TextField(unique=True, blank=True, null=True)
datetime = models.DateTimeField(auto_now_add=True)
likes = models.ManyToManyField(User, related_name="comment_likes")
.views
def comment(request, poopfact_id):
...
new_entry = Comment()
...
data = model_to_dict(new_entry)
return JsonResponse(data, safe=False)
Add this method to User model. By default user object represent itself as ID. Just replace it with username field in model (note: I am considering the 'username' is your User model field)
def __str__(self):
return self.username

How to make a field dependant on another field inside one model in django

I would like the field joinkey pass the primary key of the project into the function random_int to generate a default joinkey for every new model being created. Is there a way to do this or am I approaching this problem the wrong way?
class Project(MainAbstractModel):
users = models.ManyToManyField(User)
title = models.CharField(max_length=25, default="")
joinkey = models.IntegerField(default=random_int(self.pk))
def other_user(self):
return self.users.exclude(username=user.username)
You can just use the #property decorator to handle that.
class Project(MainAbstractModel):
users = models.ManyToManyField(User)
title = models.CharField(max_length=25, default="")
#property
def joinkey(self):
return random_int(self.pk)
#joinkey.setter
def joinkey(self, value):
# handle setting a joinkey if need be
pass
def other_user(self):
return self.users.exclude(username=user.username)

Django 1.5 ModelForm like admin in view with images and foreign key

I have the following models:
class Quiver(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
is_default = models.BooleanField(default=False)
type = models.CharField(max_length=1, choices=QUIVER_TYPES)
category = models.CharField(max_length=255, choices=QUIVER_CATEGORIES)
def __unicode__(self):
return u'[%s] %s %s quiver' % (
self.user.username,
self.get_type_display(),
self.get_category_display())
class Image(models.Model):
photo = models.ImageField(upload_to=get_upload_file_path)
is_cover = models.BooleanField(default=False)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey()
def save(self, *args, **kwargs):
try:
this = Image.objects.get(pk=self.pk)
if this.photo != self.photo:
this.photo.delete(save=False)
except Image.DoesNotExist:
pass
super(Image, self).save(*args, **kwargs)
class Surfboard(models.Model):
quiver = models.ForeignKey(Quiver)
brand = models.CharField(max_length=255)
model = models.CharField(max_length=255)
length = models.CharField(max_length=255)
width = models.CharField(max_length=255, blank=True)
thickness = models.CharField(max_length=255, blank=True)
volume = models.CharField(max_length=255, blank=True)
images = generic.GenericRelation(Image)
def __unicode__(self):
return u'%s %s %s' % (self.length, self.brand, self.model)
def get_cover_image(self):
"Returns the cover image from the images uploaded or a default one"
for image in self.images.all():
if image.is_cover:
return image
return None
I'd like to be able to have the same form I have in the admin in my frontend view /surfboard/add:
As a new Django fan and user, I started to create the form from scratch. Not being able to do what I want with including the foreign key "quiver" as a dropdown list, I found in the doc the ModelForm, and decided to use it, so here what I got:
class SurfboardForm(ModelForm):
class Meta:
model = Surfboard
In my view, it looks like this and it's already a good start:
So now, I wanted to have a way to add pictures at the same time, and they are linked to a surfboard via a Generic Relation. Here I don't find the way to do a implementation like in the admin, and get frustrated. Any tips to do so?
Thanks!
What you seek is called an inline formset - see the docs for more.
It's also handy that you can render a formset quickly with {{ formset.as_p }}, but you'll need to write some JavaScript (or use the JavaScript that's used in the Django admin) to handle adding and removing forms.

Django Assign M2M after Saving

I'm working on a project in Django and I have the following problem:
I have these two classes, Team and Project. When I create one project I want to automatically assign users from the team what was selected when I created the Project to the new project.
I override Project's save method and after the project was created assign users to the project(I did after saving because, before gave me an error). I tried of several ways but none of them works.
Tried by:
self.user.add(*self.team.users.all())
self.save()
And this doesn't work.
Tried iterating:
for uTeam in self.team.users.all():
self.users.add(uTeam)
and doesn't work either.
The only way that work for me is this, but only in the Django Shell:
P = Project.objects.get(pk=1)
T = Team.objects.get(pk=1)
P.user.add(*T.user.all())
P.save()
This is the solution that I have below but doesn't work in Django(gives an infinite loop)
class Team(models.Model):
name = models.CharField(max_length=200,
help_text=_('name of the team'))
user = models.ManyToManyField(settings.AUTH_USER_MODEL,
related_name="members_of_team",
help_text=_('users of the team'),
null=True
)
and more....
class Project(models.Model):
id = models.AutoField(primary_key=True, null=False)
name = models.CharField(max_length=200,
help_text=_('name of project'),
)
team = models.ForeignKey(Team,`enter code here`
on_delete=models.PROTECT,
help_text=_('team of project'))
created_by = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.PROTECT,
related_name='creator_project',
blank=True,
null=False,
help_text=_('project created by'))
customer = models.ForeignKey(Customer,
on_delete=models.PROTECT,
help_text=_('customer'))
user = models.ManyToManyField(settings.AUTH_USER_MODEL,
related_name='users_team',
blank=True,
null=False,
help_text=_('users of this project'))
def save(self, *args, **kwargs):
if self.checkIntegrity():
super(Project, self).save(*args, **kwargs)
if self.user.all().count() < self.team.user.all().count():
T = Team.objects.get(pk=self.team.id)
P = Project.objects.get(pk=self.id)
P.user.add(*T.user.all())
P.save()
Thank you for your help
I got it, I read that m2m fields are filled after save() and post_save() and there is a signal that trigger when a m2m field is changed so I write the following:
#receiver(m2m_changed, sender=Project.user.through)
def m2mChange(sender, **kwargs):
instance = kwargs['instance']
T = Team.objects.get(pk=instance.team.id)
if kwargs['pk_set'] is None:
instance.user.add(*T.user.all())
And now it works fine.
Thank you for all.

Django - Form validation error

I have a model like this:
class Entity(models.Model):
entity_name = models.CharField(max_length=100)
entity_id = models.CharField(max_length=30, primary_key=True)
entity_parent = models.CharField(max_length=100, null=True)
photo_id = models.CharField(max_length=100, null=True)
username = models.CharField(max_length=100, null=True)
date_matched_on = models.CharField(max_length=100, null=True)
status = models.CharField(max_length=30, default="Checked In")
def __unicode__(self):
return self.entity_name
class Meta:
app_label = 'match'
ordering = ('entity_name','date_matched_on')
verbose_name_plural='Entities'
I also have a view like this:
def photo_match(request):
''' performs an update in the db when a user chooses a photo '''
form = EntityForm(request.POST)
form.save()
And my EntityForm looks like this:
class EntityForm(ModelForm):
class Meta:
model = Entity
My template's form returns a POST back to the view with the following values:
{u'username': [u'admin'], u'entity_parent': [u'PERSON'], u'entity_id': [u'152097'], u'photo_id': [u'2200734'], u'entity_name': [u'A.J. McLean'], u'status': [u'Checked Out'], u'date_matched_on': [u'5/20/2010 10:57 AM']}
And form.save() throws this error:
Exception in photo_match: The Entity could not be changed because the data didn't validate.
I have been trying to figure out why this is happening, but cannot pinpoint the exact problem. I can change my Entities in the admin interface just fine. If anybody has a clue about this I would greatly appreciate it!
Thanks,
Igor
If the entity you are trying to update is already saved, then you need to provide an instance parameter when you bind the form, otherwise save will try to perform an INSERT rather than an UPDATE, and the new object won't validate (check out the django docs here).
Try:
def photo_match(request):
''' performs an update in the db when a user chooses a photo '''
entity = Entity.objects.get(pk=request.POST['entity_id'])
form = EntityForm(request.POST, instance=entity)
form.save()
You'll want to be a little more robust about the way you look up the entity, of course.