python forms - Django ModelForm, um eine versteckte Eingabe zu haben




fields hidden (4)

Ich war auf der Suche nach einem Weg, um alle Eingänge zu verstecken:

class TagStatusForm(forms.ModelForm):
    class Meta:
        model = TagStatus

    def __init__(self, *args, **kwargs):
        super(TagStatusForm, self).__init__(*args, **kwargs)
        for field in self.fields:
            self.fields[field].widget = forms.HiddenInput()

Also ich habe mein TagStatus-Modell. Ich versuche ein ModelForm dafür zu machen. In meinem Formular muss jedoch die versteckte Eingabe mit {{tag.name}} gefüllt sein. Ich habe die Dokumente durchgesehen und weiß nicht, wie ich das Tag-Feld zu einem versteckten Input machen kann. Vielleicht ist ein ModelForm nicht der richtige Weg?

models.py:

class TagStatus(models.Model):
    user = models.ForeignKey(User, null=True, unique=True)
    status = models.CharField(max_length=2, choices=tag_statuses)
    tag = models.ForeignKey(Tag, null=True, blank=True)

    def __unicode__(self):
        return self.status

    def save(self, *args, **kwargs):
        super(TagStatus, self).save(*args, **kwargs)

class TagStatusForm(modelForm):
    class Meta:
        model = TagStatus
        fields = ('status','tag') 
        widgets = {
             'select': Select,
             'tag': ???
        }

django ansichten.py:

@login_required
def tags(request):
    all_tags = Tag.objects.all()
    context = base_context(request)
    if request.method == 'POST':
        if 'status_check' in request.POST:
            status_form = TagStatusForm(request.POST)
            #if request.is_ajax():
            if status_form.is_valid():
                status_form.save()
                response = simplejson.dumps({"status": "Successfully changed status"})
            else:
                response = simplejson.dumps({"status": "Error"})
                return HttpResponse (response, mimetype='application/json')
    status_form = TagStatusForm()
    context['status_form'] = status_form
    context['all_tags'] = all_tags
    return render_to_response('tags/tags.html', context, context_instance=RequestContext(request))

Vorlage:

{% for tag in all_tags %}
....
<form class="nice" id="status-form" method="POST" action="">
     {% csrf_token %}
      <input type="hidden" name="status_check" />
      <input type='hidden' name="tag" value="{{ tag.name }}" />
     {{ status_form.status }}
</form>
...
{% endfor %}

Wie würde ich eine versteckte Eingabe über ein Django ModelForm machen und sie dann durch die Vorlage füllen?


Verwenden Sie ein HiddenInput-Widget, um ein Feld in einem ModelField zu einem ausgeblendeten Feld zu machen. Das ModelForm verwendet ein sinnvolles Standardwidget für alle Felder. Sie müssen es nur überschreiben, wenn das Objekt erstellt wird.

class TagStatusForm(forms.ModelForm):
    class Meta:
        model = TagStatus
        widgets = {'tag': forms.HiddenInput()}

Es gibt 3 Möglichkeiten (AFAIK) um versteckte Felder in Django zu rendern -

1. Sie könnten ein Feld normal in forms.py aber in Ihrer HTML-Datei verwenden Sie {{ form.field.as_hidden }}

2. forms.py in forms.py direkt das versteckte Eingabe-Widget.

class MyForm(forms.Form):
    hidden_field = forms.CharField(widget=forms.HiddenInput())

Sobald Sie das Feld zu einer versteckten Eingabe machen, können Sie den Wert des Feldes in Templates auffüllen. Jetzt ist Ihr verstecktes Feld zum Rendern bereit.

3. Normalformäquivalent (Danke an @Modelesq für die Freigabe dieses Nuggets). Hier ist kein Django beteiligt. Änderungen werden auf HTML-Vorlagenebene vorgenommen. <input type="hidden" name="tag" value="{{ tag.name }}" />


So erstellen Sie Beispieldatensätze

Dies soll vor allem die Antwort von @ AndyHayden erweitern, indem es Beispiele dafür liefert, wie Sie Beispieldatenrahmen erstellen können. Pandas und (vor allem) numpy bieten Ihnen dafür eine Vielzahl von Tools, mit denen Sie in der Regel mit nur wenigen Zeilen Code ein praktisches Faksimile eines realen Datensatzes erstellen können.

Stellen Sie nach dem Import von numpy und pandas sicher, dass Sie einen zufälligen Startwert angeben, wenn Sie möchten, dass Ihre Daten und Ergebnisse genau reproduziert werden können.

import numpy as np
import pandas as pd

np.random.seed(123)

Ein Küchenspülbeispiel

Hier ist ein Beispiel, das eine Vielzahl von Dingen zeigt, die Sie tun können. Alle Arten von nützlichen Beispieldatenrahmen könnten aus einer Teilmenge davon erstellt werden:

df = pd.DataFrame({ 

    # some ways to create random data
    'a':np.random.randn(6),
    'b':np.random.choice( [5,7,np.nan], 6),
    'c':np.random.choice( ['panda','python','shark'], 6),

    # some ways to create systematic groups for indexing or groupby
    # this is similar to r's expand.grid(), see note 2 below
    'd':np.repeat( range(3), 2 ),
    'e':np.tile(   range(2), 3 ),

    # a date range and set of random dates
    'f':pd.date_range('1/1/2011', periods=6, freq='D'),
    'g':np.random.choice( pd.date_range('1/1/2011', periods=365, 
                          freq='D'), 6, replace=False) 
    })

Dies produziert:

          a   b       c  d  e          f          g
0 -1.085631 NaN   panda  0  0 2011-01-01 2011-08-12
1  0.997345   7   shark  0  1 2011-01-02 2011-11-10
2  0.282978   5   panda  1  0 2011-01-03 2011-10-30
3 -1.506295   7  python  1  1 2011-01-04 2011-09-07
4 -0.578600 NaN   shark  2  0 2011-01-05 2011-02-27
5  1.651437   7  python  2  1 2011-01-06 2011-02-03

Einige Notizen:

  1. np.repeat und np.tile (Spalten d und e ) sind sehr nützlich, um Gruppen und Indizes sehr regelmäßig zu erstellen. Für 2 Spalten kann dies verwendet werden, um r's expand.grid() einfach zu duplizieren, ist aber auch flexibler in der Fähigkeit, eine Teilmenge aller Permutationen bereitzustellen. Bei 3 oder mehr Spalten wird die Syntax jedoch schnell unhandlich.
  2. Für einen direkteren Ersatz für r's expand.grid() siehe die itertools Lösung im pandas-Kochbuch oder die np.meshgrid gezeigte np.meshgrid Lösung. Diese erlauben eine beliebige Anzahl von Dimensionen.
  3. Mit np.random.choice können Sie einiges np.random.choice . Zum Beispiel haben wir in Spalte g eine zufällige Auswahl von 6 Daten von 2011. Außerdem können wir durch das Setzen von replace=False sicherstellen, dass diese Daten eindeutig sind - sehr praktisch, wenn wir dies als Index mit eindeutigen Werten verwenden wollen.

Fake Börsendaten

Zusätzlich zu Teilmengen des obigen Codes können Sie die Techniken weiter kombinieren, um fast alles zu tun. Im np.tile date_range ein kurzes Beispiel, das np.tile und date_range kombiniert, um Beispiel- date_range für 4 Stocks zu erstellen, die dieselben Daten enthalten:

stocks = pd.DataFrame({ 
    'ticker':np.repeat( ['aapl','goog','yhoo','msft'], 25 ),
    'date':np.tile( pd.date_range('1/1/2011', periods=25, freq='D'), 4 ),
    'price':(np.random.randn(100).cumsum() + 10) })

Jetzt haben wir ein Beispiel-Dataset mit 100 Zeilen (25 Daten pro Ticker), aber wir haben nur 4 Zeilen dafür verwendet, so dass es für alle anderen einfach ist, ohne Kopieren und Einfügen von 100 Zeilen Code zu reproduzieren. Sie können dann Teilmengen der Daten anzeigen, wenn es hilft, Ihre Frage zu erklären:

>>> stocks.head(5)

        date      price ticker
0 2011-01-01   9.497412   aapl
1 2011-01-02  10.261908   aapl
2 2011-01-03   9.438538   aapl
3 2011-01-04   9.515958   aapl
4 2011-01-05   7.554070   aapl

>>> stocks.groupby('ticker').head(2)

         date      price ticker
0  2011-01-01   9.497412   aapl
1  2011-01-02  10.261908   aapl
25 2011-01-01   8.277772   goog
26 2011-01-02   7.714916   goog
50 2011-01-01   5.613023   yhoo
51 2011-01-02   6.397686   yhoo
75 2011-01-01  11.736584   msft
76 2011-01-02  11.944519   msft




python django django-models django-forms