14

Próbuję uzyskać dostęp do kluczy obcych w widokach opartych na klasie CreateView. Chciałbym móc dynamicznie ustawiać początkowe wartości w CBV z ForeignKeys oraz dynamicznie ustawiać linki szablonów z ForeignKeys.Ustaw początkową wartość w CreateView z ForeignKey (non-self.request.user)

Te dwa pytania (1., 2. Wartości początkowe linki template) może być rozwiązany w podobnych metod, czy może za pomocą różnych metod ... wciąż się uczę. Być może pierwsze pytanie można rozwiązać w ramach views.py, a drugie pytanie można rozwiązać za pomocą składni szablonu w ingredient_form.html?

Widziałem pytania dotyczące wartości początkowych ustawień SO od użytkowników (self.request.user), ale nie od zwykłego klucza obcego z models.py.

Idę przez django-by-errors i próbuje dodać dodatkowe funkcje, aby rozwinąć swoją wiedzę Django.

Moje pytanie szczególnie skupia się na views.py:IngredientAddView(CreateView) na ingredient_form.html, a na urls.py:'recipe-detail' & 'ingredient-add”.

Po wyświetleniu 'recipe-detail' mogę kliknąć łącze do 'ingredient-add'. Chciałbym, aby 'ingredient-add' "wiedział", który przepis kliknął, i móc ustawić ten przepis jako wartość początkową (moja próba w ramach views.py:IngredientAddView:get_initials(self) nie działa), a także być w stanie powrócić do tego przepisu (moja próba w ramach ingredient_form.html:{% comment %} nie działa).

Byłbym wdzięczny za wszelką pomoc.

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

myślę łatwy sposób zrobić to, co pytasz jest mieć url pK 'receptury-detail 'w tym. Coś jak '/ twój_url/13'. Widok może następnie użyć tego pk, aby przypisać konkretną instancję FK. –

+0

Zgadzam się, że korzystanie z pk dla adresu URL jest łatwiejsze - ale wyobrażam sobie aplikację internetową, która jest przyjazna dla użytkownika przy użyciu sensownych adresów URL. Chciałbym także poszerzyć swoją wiedzę o django. – Jeremiah

Odpowiedz

20

Musisz instancję swój przepis:

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. To zadziałało. Dziękuję Ci. Dla przyszłego odniesienia, funkcja jest w rzeczywistości 'get_initial (self)' ale to była moja wina dla początkowego literówki. – Jeremiah

+0

Masz rację, poprawiłem odpowiedź. Pisałem też z mojej głowy. :-) –