1

I'm trying to make a view where the user can edit DB records through a form in a template. I've searched a lot of web pages (and Django docs as well) where they teach how to make these views, but they always use the "id" that Django generates for each Model. In this particular Model, I have to use an AutoField to override the "id". Is there a way to use this AutoField as an "id" of the record with Django?

Here's my complete model:

class T031003 (models.Model): 
   C003IDCD = AutoField(primary_key=True)
   C003INST = models.IntegerField(unique=True) #usar AutoSlug
   C003TPCD = models.CharField(max_length=1)
   C003CHCD = models.CharField(max_length=14)
   C003MTR = models.CharField(max_length=30, blank=True, null=True)
   C003CTCD = models.CharField(max_length=3)
   C003RZSC = models.CharField(max_length=60, blank=True, null=True)
   C003EML = models.EmailField(max_length = 254, blank=True, null=True)
   C003LOGA = models.CharField(max_length=20)
   C003LOGB = models.DateTimeField()
   C003LOGD = models.CharField(max_length=15, blank=True, null=True)
   C003LOGF = models.CharField(max_length=20, blank=True, null=True)

   def __unicode__(self):
       return '%s' %  self.C003MTR

   class T031003Form(ModelForm):
       class Meta:
          model = T031003
          ordering = ["-C003MTR"]
          exclude = ('C003LOGA','C003LOGB','C003LOGD','C003LOGE','C003LOGF')

And here's the view I tried to do, but it gives me the error "No T031003 matches the given query." and it's right, since there is no "id" in the table:

def t031003form_edit(request, id=None):
pin = get_object_or_404(T031003, pk=id)
form = T031003Form(request.POST or None, instance=pin)
if request.method == 'POST':
    if form.is_valid():
        form = form.save(False)
        form.C003LOGA = request.user
        form.C003LOGB = datetime.date.today()
        form.C003LOGD = request.META['REMOTE_ADDR']
        form.C003LOGF = request.META['USERDOMAIN']
        form.save()
        form = T031003Form()
    else:
        return HttpResponseRedirect('/erro/')
return render_to_response('T031003Form_edit.html', {'form': form,}, context_instance=RequestContext(request))

Any help would be very appreciated!

Charles
  • 50,943
  • 13
  • 104
  • 142

2 Answers2

0

If a model has an AutoField — an auto-incrementing primary key — then that auto-incremented value will be calculated and saved as an attribute on your object the first time you call save():

>>> b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.')
>>> b2.id     # Returns None, because b doesn't have an ID yet.
>>> b2.save()
>>> b2.id     # Returns the ID of your new object.

There's no way to tell what the value of an ID will be before you call save(), because that value is calculated by your database, not by Django.

ref : https://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs

dilip kumbham
  • 703
  • 6
  • 15
  • Thanks for the explanation! So, if I already have a couple of records inside that database and I don't have the "id" because of the AutoField I used in my model has overridden it, how can I edit one precise record? Which parameters should I pass to the method? –  Jun 12 '12 at 16:59
  • If I'm not giving the "id" as a parameter to identify what record inside the database I want to modify, `def t031003form_edit(request, id=None):` then what should I pass? For example, inside the "def", if I set pk=1 instead of pk=id, it always picks the first record of the table to modify through the view. But if I want to modify any record through a view, how can I identify which record I'm modifying? Thanks for your patience, it's just that this thing is a little rough for me to understand how it works. –  Jun 12 '12 at 17:23
  • In your code, change C003IDCD = models.AutoField(primary_key=True) and if you want to deal with object of your model in view you need to save the object first to get the id or you can just work with the model name instead of objects – dilip kumbham Jun 13 '12 at 01:59
0

Well, thanks to the help from a close friend, I could do the trick using formsets. Here's the view:

def t031002form_edit(request, id_auto):
j = get_object_or_404(T031002, pk=id_auto)

T031003FormSet = modelformset_factory(T031002, can_delete=True, max_num=1)

if request.method == 'POST':
    form = T031002FormSet(request.POST or None, request.FILES or None, queryset=T031002.objects.filter(pk=id_auto)) 
    if form.is_valid():
        instance = form.save(commit=False)
        form.C003LOGA = request.user
        form.C003LOGB = datetime.date.today()
        form.C003LOGD = request.META['REMOTE_ADDR']
        form.C003LOGF = request.META['USERDOMAIN']
        for reform in instance:
            reform.save()
    else:
       return HttpResponseRedirect('/erro/')
else:
    form = T031002FormSet(queryset=T031002.objects.filter(pk=id_auto))  
return render_to_response(('T031002Form_edit.html'), {'form': form,}, context_instance=RequestContext(request))

So, with formsets, you can work nicely and with no worries. Hope it helps others with this same questioning.

  • Just a little thing extra: that "id_auto" is a value that you will pass through the url. In your urls.py you will have `url(r'^t031002form_edit/(?P\d+)/', 'Mod031.views.t031002form_edit')` and in the template, you will pass something like: /t031002form_edit/1/ This will lead you to the record in the DB where it's "id" is equal to 1 (and the id in this case is the AutoField). –  Jun 25 '12 at 16:21