14

Sto tentando di accedere a ForeignKeys nelle viste basate su classi CreateView. Mi piacerebbe essere in grado di impostare dinamicamente i valori iniziali in CBV da ForeignKeys e anche di impostare dinamicamente i collegamenti dei modelli da ForeignKeys.imposta il valore iniziale in CreateView da ForeignKey (non-self.request.user)

Queste due domande (1. valori iniziali, 2. collegamenti di modello) possono essere risolti in metodi simili, o forse con metodi diversi ... Sto ancora imparando. Forse la prima domanda può essere risolta entro views.py e la seconda domanda può essere risolta con la sintassi del modello in ingredient_form.html?

Ho visto domande su SO che impostano i valori iniziali dagli utenti (self.request.user), ma non solo da una normale chiave esterna in models.py.

Sto passando attraverso django-by-errors e sto tentando di aggiungere funzionalità extra per espandere la mia conoscenza di django.

La mia domanda concentra in particolare sulla views.py:IngredientAddView(CreateView), su ingredient_form.html, e urls.py:'recipe-detail' & 'ingredient-add'.

Quando visualizzo uno 'recipe-detail', posso fare clic su un collegamento su 'ingredient-add'. Vorrei che lo "'ingredient-add'" sapesse "su quale ricetta si è cliccato e che sia in grado di impostare questa ricetta come valore iniziale (il mio tentativo entro views.py:IngredientAddView:get_initials(self) non funziona), e anche essere in grado di ricollegarmi a questa ricetta (il mio tentativo entro ingredient_form.html:{% comment %} non funziona).

Apprezzerebbero qualsiasi assistenza.

models.py

class Food(models.Model): 
    name=models.CharField(max_length=20,unique=True) 

    def __str__(self): 
     return self.name 

    def get_absolute_url(self): 
     return reverse('food-detail',kwargs={'pk':self.pk}) 

class Recipe(models.Model): 
    title=models.CharField(max_length=80,unique=True) 
    slug=models.SlugField(max_length=80,unique=True) 
    description=models.TextField(blank=True) 

    def __str__(self): 
     return self.title 

    def get_absolute_url(self): 
     return reverse('recipe-detail',kwargs={'slug':self.slug}) 

class Ingredient(models.Model): 
    recipe=models.ForeignKey(Recipe) 
    food=models.ForeignKey(Food) 

    def __str__(self): 
     return '%s (%s)' % (self.food, self.recipe) 

views.py

class FoodListView(ListView): 
    model=Food 

class FoodDetailView(DetailView): 
    model=Food 

class FoodCreateView(CreateView): 
    model=Food 

class RecipeListView(ListView): 
    model=Recipe 

class RecipeDetailView(DetailView): 
    model=Recipe 

class RecipeCreateView(CreateView): 
    model=Recipe 

class RecipeUpdateView(UpdateView): 
    model=Recipe 

class IngredientAddView(CreateView): 
    model=Ingredient 

# def get_context_data(self,**kwargs): 
#  context=super(IngredientAddView,self).get_context_data(**kwargs) 
#  context['foreign']=self.request.session.get('slug') 

    def get_initials(self): 
     return { 
      'recipe':self.request.session.get('recipe') 
     } 

urls.py

from .views import FoodListView, FoodDetailView, FoodCreateView, RecipeListView, RecipeDetailView, RecipeCreateView, RecipeUpdateView, IngredientAddView 

urlpatterns=patterns('', 
        url(r'^$',RecipeListView.as_view(),name='recipe-list'), 
        url(r'^(?P<slug>[-\w]+)$',RecipeDetailView.as_view(),name='recipe-detail'), 
        url(r'^(?P<slug>[-\w]+)/edit$',RecipeUpdateView.as_view(),name='recipe-edit'), 
        url(r'^(?P<slug>[-\w]+)/add_ingredient/$',IngredientAddView.as_view(),name='ingredient-add'), 
        url(r'^new/$',RecipeCreateView.as_view(),name='recipe-create'), 
        url(r'^food/$',FoodListView.as_view(),name='food-list'), 
        url(r'^food/(?P<pk>[\d]+)$',FoodDetailView.as_view(),name='food-detail'), 
        url(r'^food/create/$',FoodCreateView.as_view(),name='food-create'), 
       ) 

recipe_detail.html

{% extends "base_food.html" %} 

{% block title %}{{ recipe }} {% endblock %} 

{% block content %} 
    <h1>{{ recipe }}</h1> 
    <p>{{ recipe.id }}</p> 
    <p>{{ recipe.title }}</p> 

    <br> 
    <h2>Description</h2> 
    <p>{{ recipe.description|default:'No description' }}</p> 

    <h2>Ingredients</h2> 
    <ul> 
    {% for ingredient in recipe.ingredient_set.all %} 
     <li>{{ ingredient }}</li> 
    {% endfor %} 
    </ul> 
    <p><a href="{% url 'ingredient-add' recipe.slug %}">Add ingredient</a></p> 
    <p><a href="{% url 'recipe-edit' recipe.slug %}">Edit recipe</a></p> 
    <p><a href="{% url 'recipe-list' %}">Back to recipe list</a></p> 
{% endblock %} 

ingredient_form.html

{% extends "base_food.html" %} 

{% block title %}Add Ingredient{% endblock %} 

{% block content %} 
    <h1>Add Ingredient</h1> 
    <form method="POST">{% csrf_token %} 
    {{ form }} 
    <button type="submit" class="btn btn-primary">Save</button> 
    </form> 

{%comment%} <p><a href="{% url 'recipe-detail' recipe.slug %}">Back to detail</a></p> {%endcomment%} 
    <p><a href="{% url 'recipe-list' %}">Back to recipe list</a></p> 
{% endblock %} 
+0

penso che il modo più semplice per fare quello che stai chiedendo è di avere un URL con il pk del 'ricetta-detail 'in esso. Qualcosa come '/ your_url/13'. La vista può quindi utilizzare quel pk per assegnare l'istanza FK specifica. –

+0

Sono d'accordo nell'usare un pk per l'url è più facile - ma immagino un'app web che sia user-friendly nell'uso di URL significativi. Mi piacerebbe anche espandere la mia conoscenza del django. – Jeremiah

risposta

20

Hai bisogno di istanziare la vostra ricetta:

class IngredientAddView(CreateView): 
    model=Ingredient 

    def get_initial(self): 
     recipe = get_object_or_404(Recipe, slug=self.kwargs.get('slug')) 
     return { 
      'recipe':recipe, 
     } 
+1

Bingo. Questo ha funzionato. Grazie. Per riferimento futuro, la funzione è in realtà 'get_initial (self)' ma è stata colpa mia per la battitura iniziale. – Jeremiah

+0

Hai ragione, ho risolto la risposta. Stavo anche scrivendo fuori di testa. :-) –

Problemi correlati